Skip to content

Commit

Permalink
Merge pull request #209 from ellneal/feature/custom-view-value
Browse files Browse the repository at this point in the history
Add view option to specify a custom emit value for views
  • Loading branch information
samlown authored Aug 20, 2016
2 parents dde59dd + 8d35dd7 commit a955c99
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
9 changes: 7 additions & 2 deletions lib/couchrest/model/designs/view.rb
Original file line number Diff line number Diff line change
Expand Up @@ -491,18 +491,23 @@ def define(design_doc, name, opts = {})
end
raise "View cannot be created without recognised name, :map or :by options" if opts[:by].nil?

# convert emit symbols to properties
opts[:emit] = "doc['#{opts[:emit]}']" if opts[:emit].try { is_a?(Symbol) }
opts[:emit] = "[" + opts[:emit].map { |i| i.is_a?(Symbol) ? "doc['#{i}']" : i }.join(', ') + "]" if opts[:emit].try { is_a?(Array) }

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(', ')}]"
emit_keys = keys.length == 1 ? keys.first : "[#{keys.join(', ')}]"
emit_value = opts[:emit] || 1;
opts[:guards] += keys.map{|k| "(#{k} != null)"} unless opts[:allow_nil]
opts[:guards] += keys.map{|k| "(#{k} != '')"} unless opts[:allow_blank]
opts[:map] = <<-EOF
function(doc) {
if (#{opts[:guards].join(' && ')}) {
emit(#{emit}, 1);
emit(#{emit_keys}, #{emit_value});
}
}
EOF
Expand Down
18 changes: 18 additions & 0 deletions spec/unit/designs/view_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,24 @@ class DesignViewModel < CouchRest::Model::Base
@klass.define(@design_doc, 'by_title', :reduce => :stats)
@design_doc['views']['by_title']['reduce'].should eql('_stats')
end

it "should allow the emit value to be overridden" do
@klass.define(@design_doc, 'by_title', :emit => :name)
str = @design_doc['views']['by_title']['map']
str.should include("emit(doc['title'], doc['name']);")
end

it "should forward a non-symbol emit value straight into the view" do
@klass.define(@design_doc, 'by_title', :emit => 3)
str = @design_doc['views']['by_title']['map']
str.should include("emit(doc['title'], 3);")
end

it "should support emitting an array" do
@klass.define(@design_doc, 'by_title', :emit => [1, :name])
str = @design_doc['views']['by_title']['map']
str.should include("emit(doc['title'], [1, doc['name']]);")
end
end

describe ".create_model_methods" do
Expand Down

0 comments on commit a955c99

Please sign in to comment.