def define(design_doc, name, opts = {})
model = design_doc.model
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?
opts[:reduce] = "_sum"
end
end
if opts[:reduce].is_a?(Symbol)
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