# File lib/couchrest/model/designs/view.rb, line 464
          def define(design_doc, name, opts = {})
            model = design_doc.model

            # Is this an all view?
            if name.to_s == 'all'
              opts[:map] = "function(doc) {\nif (doc['\#{model.model_type_key}'] == '\#{model.model_type_value}') {\nemit(doc._id, null);\n}\n}\n"
            elsif !opts[:map]
              if opts[:by].nil? && name.to_s =~ /^by_(.+)/
                opts[:by] = $1.split(/_and_/)
              end
              raise "View cannot be created without recognised name, :map or :by options" if opts[:by].nil?

              opts[:allow_blank] = opts[:allow_blank].nil? ? true : opts[:allow_blank]
              opts[:guards] ||= []
              opts[:guards].push "(doc['#{model.model_type_key}'] == '#{model.model_type_value}')"

              keys = opts[:by].map{|o| "doc['#{o}']"}
              emit = keys.length == 1 ? keys.first : "[#{keys.join(', ')}]"
              opts[:guards] += keys.map{|k| "(#{k} != null)"} unless opts[:allow_nil]
              opts[:guards] += keys.map{|k| "(#{k} != '')"} unless opts[:allow_blank]
              opts[:map] = "function(doc) {\nif (\#{opts[:guards].join(' && ')}) {\nemit(\#{emit}, 1);\n}\n}\n"
              if opts[:reduce].nil?
                # Use built-in sum function by default
                opts[:reduce] = "_sum"
              end
            end

            if opts[:reduce].is_a?(Symbol)
              # Assume calling a built in method, convert to a string
              opts[:reduce] = "_#{opts[:reduce]}"
            end

            design_doc['views'] ||= {}
            view = design_doc['views'][name.to_s] = { }
            view['map'] = opts[:map]
            view['reduce'] = opts[:reduce] if opts[:reduce]
            view
          end