Skip to content

Commit

Permalink
Scopes now work with queries and are inherited. (ie: scope :johns, wh…
Browse files Browse the repository at this point in the history
…ere(:name => 'John'))
  • Loading branch information
jnunemaker committed Jun 15, 2010
1 parent 16ca4ec commit 1744f38
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 6 deletions.
8 changes: 4 additions & 4 deletions lib/mongo_mapper/plugins/scopes.rb
Expand Up @@ -4,15 +4,15 @@ module Scopes
module ClassMethods
def scope(name, scope_options={})
scopes[name] = lambda do |*args|
options = scope_options.is_a?(Proc) ? scope_options.call(*args) : scope_options
self.query(options)
result = scope_options.is_a?(Proc) ? scope_options.call(*args) : scope_options
result = self.query(result) if result.is_a?(Hash)
self.query.merge(result)
end

singleton_class.send :define_method, name, &scopes[name]
end

def scopes
@scopes ||= {}
read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
end
end
end
Expand Down
63 changes: 61 additions & 2 deletions test/functional/test_scopes.rb
Expand Up @@ -39,8 +39,9 @@ class ScopesTest < Test::Unit::TestCase
context "dynamic scopes" do
setup do
@document.class_eval do
scope :age, lambda { |age| {:age => age} }
scope :ages, lambda { |low, high| {:age.gte => low, :age.lte => high} }
scope :age, lambda { |age| {:age => age} }
scope :ages, lambda { |low, high| {:age.gte => low, :age.lte => high} }
scope :ordered, lambda { |sort| sort(sort) }
end
end

Expand All @@ -60,6 +61,31 @@ class ScopesTest < Test::Unit::TestCase
docs.size.should == 2
docs.map(&:name).sort.should == %w(Frank John)
end

should "work with queries" do
john = @document.create(:name => 'John', :age => 60)
frank = @document.create(:name => 'Frank', :age => 50)
bill = @document.create(:name => 'Bill', :age => 40)
@document.ordered(:age).all.should == [bill, frank, john]
end
end

context "query scopes" do
setup do
@document.class_eval do
scope :boomers, where(:age.gte => 60).sort(:age)
end
end

should "work" do
todd = @document.create(:name => 'Todd', :age => 65)
john = @document.create(:name => 'John', :age => 60)
@document.create(:name => 'Frank', :age => 50)
@document.create(:name => 'Bill', :age => 40)
docs = @document.boomers.all
docs[0].should == john
docs[1].should == todd
end
end

context "chaining" do
Expand Down Expand Up @@ -108,5 +134,38 @@ def self.young
end
end
end

context "with single collection inheritance" do
setup do
class ::Item
include MongoMapper::Document
scope :by_title, lambda { |title| {:title => title} }
scope :published, lambda { {:published_at.lte => Time.now.utc} }

key :title, String
key :published_at, Time
end
Item.collection.remove

class ::Page < ::Item; end
class ::Blog < ::Item; end
end

teardown do
Object.send :remove_const, 'Item' if defined?(::Item)
Object.send :remove_const, 'Page' if defined?(::Page)
Object.send :remove_const, 'Blog' if defined?(::Blog)
end

should "inherit scopes" do
Page.scopes.keys.map(&:to_s).sort.should == %w(by_title published)
end

should "work with _type" do
item = Item.create(:title => 'Home')
page = Page.create(:title => 'Home')
Page.by_title('Home').first.should == page
end
end
end
end

0 comments on commit 1744f38

Please sign in to comment.