Skip to content

Commit

Permalink
Added scope chaining.
Browse files Browse the repository at this point in the history
  • Loading branch information
jnunemaker committed Jun 15, 2010
1 parent f37e1d2 commit 0b5a213
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 2 deletions.
14 changes: 14 additions & 0 deletions lib/mongo_mapper/plugins/querying/decorator.rb
Expand Up @@ -30,6 +30,20 @@ def first(opts={})
def last(opts={})
model.load(super)
end

private
def method_missing(method, *args, &block)
if model.respond_to?(method)
query = model.send(method, *args, &block)
if query.is_a?(Plucky::Query)
merge(query)
else
super
end
else
super
end
end
end
end
end
Expand Down
54 changes: 52 additions & 2 deletions test/functional/test_scopes.rb
Expand Up @@ -35,7 +35,7 @@ class ScopesTest < Test::Unit::TestCase
docs[0].name.should == 'John'
end
end

context "dynamic scopes" do
setup do
@document.class_eval do
Expand All @@ -51,7 +51,7 @@ class ScopesTest < Test::Unit::TestCase
docs.size.should == 1
docs.first.name.should == 'John'
end

should "work with multiple arguments" do
@document.create(:name => 'John', :age => 60)
@document.create(:name => 'Frank', :age => 50)
Expand All @@ -61,5 +61,55 @@ class ScopesTest < Test::Unit::TestCase
docs.map(&:name).sort.should == %w(Frank John)
end
end

context "chaining" do
setup do
@document.class_eval do
scope :by_age, lambda { |age| {:age => age} }
scope :by_name, lambda { |name| {:name => name} }
end
end

should "work with scope methods" do
@document.create(:name => 'John', :age => 60)
@document.create(:name => 'Frank', :age => 60)
@document.create(:name => 'Bill', :age => 50)
docs = @document.by_age(60).by_name('John').all
docs.size.should == 1
docs.first.name.should == 'John'
end

should "work on query methods" do
@document.create(:name => 'John', :age => 60)
@document.create(:name => 'John', :age => 50)
@document.create(:name => 'Bill', :age => 50)
docs = @document.where(:name => 'John').by_age(50).all
docs.size.should == 1
docs.first.age.should == 50
end

should "work if method on model returns a query" do
@document.create(:name => 'John', :age => 10)
@document.create(:name => 'John', :age => 20)
@document.class_eval do
def self.young
query(:age.lte => 12)
end
end
docs = @document.by_name('John').young.all
docs.size.should == 1
docs.first.age.should == 10
end

should "not work if method on model, but return not a query" do
@document.class_eval do
def self.age
20
end
end

lambda { @document.by_name('John').age }.should raise_error(NoMethodError)
end
end
end
end

0 comments on commit 0b5a213

Please sign in to comment.