Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Bug fix: Fixed issue where instance level modifiers don't work on a mode... #422

Merged
merged 1 commit into from

2 participants

@andrewtimberlake

Fixed issue where instance level modifiers don't work on a model with a compound (hash) id key

@andrewtimberlake

Addresses issue: #421

@jnunemaker jnunemaker merged commit f205122 into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 2, 2012
  1. @andrewtimberlake

    Bug fix: Fixed issue where instance level modifiers don't work on a m…

    andrewtimberlake authored
    …odel with a compound (hash) id key
This page is out of date. Refresh to see the latest.
Showing with 242 additions and 221 deletions.
  1. +13 −13 lib/mongo_mapper/plugins/modifiers.rb
  2. +229 −208 test/functional/test_modifiers.rb
View
26 lib/mongo_mapper/plugins/modifiers.rb
@@ -71,7 +71,7 @@ def modifier_update(modifier, args)
collection.update(criteria, {modifier => updates}, options.merge(:multi => true))
else
collection.update(criteria, {modifier => updates}, :multi => true)
- end
+ end
end
def criteria_and_keys_from_args(args)
@@ -84,51 +84,51 @@ def criteria_and_keys_from_args(args)
criteria = {:id => split_args[0]}
updates = split_args[1].first
options = split_args[1].last
- end
+ end
[criteria_hash(criteria).to_hash, updates, options]
end
end
def unset(*args)
- self.class.unset(id, *args)
+ self.class.unset({:_id => id}, *args)
end
def increment(hash, options=nil)
- self.class.increment(id, hash, options)
+ self.class.increment({:_id => id}, hash, options)
end
def decrement(hash, options=nil)
- self.class.decrement(id, hash, options)
+ self.class.decrement({:_id => id}, hash, options)
end
def set(hash, options=nil)
- self.class.set(id, hash, options)
+ self.class.set({:_id => id}, hash, options)
end
def push(hash, options=nil)
- self.class.push(id, hash, options)
+ self.class.push({:_id => id}, hash, options)
end
def push_all(hash, options=nil)
- self.class.push_all(id, hash, options)
+ self.class.push_all({:_id => id}, hash, options)
end
def pull(hash, options=nil)
- self.class.pull(id, hash, options)
+ self.class.pull({:_id => id}, hash, options)
end
def pull_all(hash, options=nil)
- self.class.pull_all(id, hash, options)
+ self.class.pull_all({:_id => id}, hash, options)
end
def add_to_set(hash, options=nil)
- self.class.push_uniq(id, hash, options)
+ self.class.push_uniq({:_id => id}, hash, options)
end
alias push_uniq add_to_set
def pop(hash, options=nil)
- self.class.pop(id, hash, options)
+ self.class.pop({:_id => id}, hash, options)
end
end
end
-end
+end
View
437 test/functional/test_modifiers.rb
@@ -2,7 +2,16 @@
class ModifierTest < Test::Unit::TestCase
def setup
- @page_class = Doc do
+ @page_class_with_compound_key = Doc do
+ key :_id, :default => -> { {n: 42, i: BSON::ObjectId.new} }
+ key :title, String
+ key :day_count, Integer, :default => 0
+ key :week_count, Integer, :default => 0
+ key :month_count, Integer, :default => 0
+ key :tags, Array
+ end
+
+ @page_class_with_standard_key = Doc do
key :title, String
key :day_count, Integer, :default => 0
key :week_count, Integer, :default => 0
@@ -18,30 +27,34 @@ def assert_page_counts(page, day_count, week_count, month_count)
page.month_count.should == month_count
end
- def assert_keys_removed(page, *keys)
+ def assert_keys_removed(page_class, page, *keys)
keys.each do |key|
- doc = @page_class.collection.find_one({:_id => page.id})
+ doc = page_class.collection.find_one({:_id => page.id})
doc.keys.should_not include(key)
end
end
context "ClassMethods" do
+ setup do
+ @page_class = @page_class_with_standard_key
+ end
+
context "unset" do
setup do
@page = @page_class.create(:title => 'Home', :tags => %w(foo bar))
@page2 = @page_class.create(:title => 'Home')
end
-
+
should "work with criteria and keys" do
@page_class.unset({:title => 'Home'}, :title, :tags)
- assert_keys_removed @page, :title, :tags
- assert_keys_removed @page2, :title, :tags
+ assert_keys_removed @page_class, @page, :title, :tags
+ assert_keys_removed @page_class, @page2, :title, :tags
end
-
+
should "work with ids and keys" do
@page_class.unset(@page.id, @page2.id, :title, :tags)
- assert_keys_removed @page, :title, :tags
- assert_keys_removed @page2, :title, :tags
+ assert_keys_removed @page_class, @page, :title, :tags
+ assert_keys_removed @page_class, @page2, :title, :tags
end
context "additional options (upsert & safe)" do
@@ -71,98 +84,98 @@ def assert_keys_removed(page, *keys)
end
end
end
-
+
context "increment" do
setup do
@page = @page_class.create(:title => 'Home')
@page2 = @page_class.create(:title => 'Home')
end
-
+
should "work with criteria and modifier hashes" do
@page_class.increment({:title => 'Home'}, :day_count => 1, :week_count => 2, :month_count => 3)
-
+
assert_page_counts @page, 1, 2, 3
assert_page_counts @page2, 1, 2, 3
end
-
+
should "work with ids and modifier hash" do
@page_class.increment(@page.id, @page2.id, :day_count => 1, :week_count => 2, :month_count => 3)
-
+
assert_page_counts @page, 1, 2, 3
assert_page_counts @page2, 1, 2, 3
end
end
-
+
context "decrement" do
setup do
@page = @page_class.create(:title => 'Home', :day_count => 1, :week_count => 2, :month_count => 3)
@page2 = @page_class.create(:title => 'Home', :day_count => 1, :week_count => 2, :month_count => 3)
end
-
+
should "work with criteria and modifier hashes" do
@page_class.decrement({:title => 'Home'}, :day_count => 1, :week_count => 2, :month_count => 3)
-
+
assert_page_counts @page, 0, 0, 0
assert_page_counts @page2, 0, 0, 0
end
-
+
should "work with ids and modifier hash" do
@page_class.decrement(@page.id, @page2.id, :day_count => 1, :week_count => 2, :month_count => 3)
-
+
assert_page_counts @page, 0, 0, 0
assert_page_counts @page2, 0, 0, 0
end
-
+
should "decrement with positive or negative numbers" do
@page_class.decrement(@page.id, @page2.id, :day_count => -1, :week_count => 2, :month_count => -3)
-
+
assert_page_counts @page, 0, 0, 0
assert_page_counts @page2, 0, 0, 0
end
end
-
+
context "set" do
setup do
@page = @page_class.create(:title => 'Home')
@page2 = @page_class.create(:title => 'Home')
end
-
+
should "work with criteria and modifier hashes" do
@page_class.set({:title => 'Home'}, :title => 'Home Revised')
-
+
@page.reload
@page.title.should == 'Home Revised'
-
+
@page2.reload
@page2.title.should == 'Home Revised'
end
-
+
should "work with ids and modifier hash" do
@page_class.set(@page.id, @page2.id, :title => 'Home Revised')
-
+
@page.reload
@page.title.should == 'Home Revised'
-
+
@page2.reload
@page2.title.should == 'Home Revised'
end
-
+
should "typecast values before querying" do
@page_class.key :tags, Set
-
+
assert_nothing_raised do
@page_class.set(@page.id, :tags => ['foo', 'bar'].to_set)
@page.reload
@page.tags.should == Set.new(['foo', 'bar'])
end
end
-
+
should "not typecast keys that are not defined in document" do
assert_raises(BSON::InvalidDocument) do
@page_class.set(@page.id, :colors => ['red', 'green'].to_set)
end
end
-
+
should "set keys that are not defined in document" do
@page_class.set(@page.id, :colors => %w[red green])
@page.reload
@@ -196,188 +209,188 @@ def assert_keys_removed(page, *keys)
end
end
end
-
+
context "push" do
setup do
@page = @page_class.create(:title => 'Home')
@page2 = @page_class.create(:title => 'Home')
end
-
+
should "work with criteria and modifier hashes" do
@page_class.push({:title => 'Home'}, :tags => 'foo')
-
+
@page.reload
@page.tags.should == %w(foo)
-
+
@page2.reload
@page2.tags.should == %w(foo)
end
-
+
should "work with ids and modifier hash" do
@page_class.push(@page.id, @page2.id, :tags => 'foo')
-
+
@page.reload
@page.tags.should == %w(foo)
-
+
@page2.reload
@page2.tags.should == %w(foo)
end
end
-
+
context "push_all" do
setup do
@page = @page_class.create(:title => 'Home')
@page2 = @page_class.create(:title => 'Home')
@tags = %w(foo bar)
end
-
+
should "work with criteria and modifier hashes" do
@page_class.push_all({:title => 'Home'}, :tags => @tags)
-
+
@page.reload
@page.tags.should == @tags
-
+
@page2.reload
@page2.tags.should == @tags
end
-
+
should "work with ids and modifier hash" do
@page_class.push_all(@page.id, @page2.id, :tags => @tags)
-
+
@page.reload
@page.tags.should == @tags
-
+
@page2.reload
@page2.tags.should == @tags
end
end
-
+
context "pull" do
setup do
@page = @page_class.create(:title => 'Home', :tags => %w(foo bar))
@page2 = @page_class.create(:title => 'Home', :tags => %w(foo bar))
end
-
+
should "work with criteria and modifier hashes" do
@page_class.pull({:title => 'Home'}, :tags => 'foo')
-
+
@page.reload
@page.tags.should == %w(bar)
-
+
@page2.reload
@page2.tags.should == %w(bar)
end
-
+
should "be able to pull with ids and modifier hash" do
@page_class.pull(@page.id, @page2.id, :tags => 'foo')
-
+
@page.reload
@page.tags.should == %w(bar)
-
+
@page2.reload
@page2.tags.should == %w(bar)
end
end
-
+
context "pull_all" do
setup do
@page = @page_class.create(:title => 'Home', :tags => %w(foo bar baz))
@page2 = @page_class.create(:title => 'Home', :tags => %w(foo bar baz))
end
-
+
should "work with criteria and modifier hashes" do
@page_class.pull_all({:title => 'Home'}, :tags => %w(foo bar))
-
+
@page.reload
@page.tags.should == %w(baz)
-
+
@page2.reload
@page2.tags.should == %w(baz)
end
-
+
should "work with ids and modifier hash" do
@page_class.pull_all(@page.id, @page2.id, :tags => %w(foo bar))
-
+
@page.reload
@page.tags.should == %w(baz)
-
+
@page2.reload
@page2.tags.should == %w(baz)
end
end
-
+
context "add_to_set" do
setup do
@page = @page_class.create(:title => 'Home', :tags => 'foo')
@page2 = @page_class.create(:title => 'Home')
end
-
+
should "be able to add to set with criteria and modifier hash" do
@page_class.add_to_set({:title => 'Home'}, :tags => 'foo')
-
+
@page.reload
@page.tags.should == %w(foo)
-
+
@page2.reload
@page2.tags.should == %w(foo)
end
-
+
should "be able to add to set with ids and modifier hash" do
@page_class.add_to_set(@page.id, @page2.id, :tags => 'foo')
-
+
@page.reload
@page.tags.should == %w(foo)
-
+
@page2.reload
@page2.tags.should == %w(foo)
end
end
-
+
context "push_uniq" do
setup do
@page = @page_class.create(:title => 'Home', :tags => 'foo')
@page2 = @page_class.create(:title => 'Home')
end
-
+
should "be able to push uniq with criteria and modifier hash" do
@page_class.push_uniq({:title => 'Home'}, :tags => 'foo')
-
+
@page.reload
@page.tags.should == %w(foo)
-
+
@page2.reload
@page2.tags.should == %w(foo)
end
-
+
should "be able to push uniq with ids and modifier hash" do
@page_class.push_uniq(@page.id, @page2.id, :tags => 'foo')
-
+
@page.reload
@page.tags.should == %w(foo)
-
+
@page2.reload
@page2.tags.should == %w(foo)
end
end
-
+
context "pop" do
setup do
@page = @page_class.create(:title => 'Home', :tags => %w(foo bar))
end
-
+
should "be able to remove the last element the array" do
@page_class.pop(@page.id, :tags => 1)
@page.reload
@page.tags.should == %w(foo)
end
-
+
should "be able to remove the first element of the array" do
@page_class.pop(@page.id, :tags => -1)
@page.reload
@page.tags.should == %w(bar)
end
end
-
+
context "additional options (upsert & safe)" do
should "be able to pass upsert option" do
new_key_value = DateTime.now.to_s
@@ -385,16 +398,16 @@ def assert_keys_removed(page, *keys)
@page_class.count(:title => new_key_value).should == 1
@page_class.first(:title => new_key_value).day_count.should == 1
end
-
+
should "be able to pass safe option" do
@page_class.create(:title => "Better Be Safe than Sorry")
-
+
# We are trying to increment a key of type string here which should fail
assert_raises(Mongo::OperationFailure) do
@page_class.increment({:title => "Better Be Safe than Sorry"}, {:title => 1}, {:safe => true})
end
end
-
+
should "be able to pass both safe and upsert options" do
new_key_value = DateTime.now.to_s
@page_class.increment({:title => new_key_value}, {:day_count => 1}, {:upsert => true, :safe => true})
@@ -405,133 +418,141 @@ def assert_keys_removed(page, *keys)
end
context "instance methods" do
- should "be able to unset with keys" do
- page = @page_class.create(:title => 'Foo', :tags => %w(foo))
- page.unset(:title, :tags)
- assert_keys_removed page, :title, :tags
- end
-
- should "be able to increment with modifier hashes" do
- page = @page_class.create
- page.increment(:day_count => 1, :week_count => 2, :month_count => 3)
-
- assert_page_counts page, 1, 2, 3
- end
-
- should "be able to decrement with modifier hashes" do
- page = @page_class.create(:day_count => 1, :week_count => 2, :month_count => 3)
- page.decrement(:day_count => 1, :week_count => 2, :month_count => 3)
-
- assert_page_counts page, 0, 0, 0
- end
-
- should "always decrement when decrement is called whether number is positive or negative" do
- page = @page_class.create(:day_count => 1, :week_count => 2, :month_count => 3)
- page.decrement(:day_count => -1, :week_count => 2, :month_count => -3)
-
- assert_page_counts page, 0, 0, 0
- end
-
- should "be able to set with modifier hashes" do
- page = @page_class.create(:title => 'Home')
- page.set(:title => 'Home Revised')
-
- page.reload
- page.title.should == 'Home Revised'
- end
-
- should "be able to push with modifier hashes" do
- page = @page_class.create
- page.push(:tags => 'foo')
-
- page.reload
- page.tags.should == %w(foo)
- end
-
- should "be able to push_all with modifier hashes" do
- page = @page_class.create
- page.push_all(:tags => %w(foo bar))
-
- page.reload
- page.tags.should == %w(foo bar)
- end
-
- should "be able to pull with criteria and modifier hashes" do
- page = @page_class.create(:tags => %w(foo bar))
- page.pull(:tags => 'foo')
-
- page.reload
- page.tags.should == %w(bar)
- end
-
- should "be able to pull_all with criteria and modifier hashes" do
- page = @page_class.create(:tags => %w(foo bar baz))
- page.pull_all(:tags => %w(foo bar))
-
- page.reload
- page.tags.should == %w(baz)
- end
-
- should "be able to add_to_set with criteria and modifier hash" do
- page = @page_class.create(:tags => 'foo')
- page2 = @page_class.create
-
- page.add_to_set(:tags => 'foo')
- page2.add_to_set(:tags => 'foo')
-
- page.reload
- page.tags.should == %w(foo)
-
- page2.reload
- page2.tags.should == %w(foo)
- end
-
- should "be able to push uniq with criteria and modifier hash" do
- page = @page_class.create(:tags => 'foo')
- page2 = @page_class.create
-
- page.push_uniq(:tags => 'foo')
- page2.push_uniq(:tags => 'foo')
-
- page.reload
- page.tags.should == %w(foo)
-
- page2.reload
- page2.tags.should == %w(foo)
- end
-
- should "be able to pop with modifier hashes" do
- page = @page_class.create(:tags => %w(foo bar))
- page.pop(:tags => 1)
-
- page.reload
- page.tags.should == %w(foo)
- end
-
- should "be able to pass upsert option" do
- page = @page_class.create(:title => "Upsert Page")
- page.increment({:new_count => 1}, {:upsert => true})
-
- page.reload
- page.new_count.should == 1
- end
-
- should "be able to pass safe option" do
- page = @page_class.create(:title => "Safe Page")
-
- # We are trying to increment a key of type string here which should fail
- assert_raises(Mongo::OperationFailure) do
- page.increment({:title => 1}, {:safe => true})
+ {:page_class_with_standard_key => "with standard key",
+ :page_class_with_compound_key => "with compound key"}.each do |page_class, description|
+ context description do
+ setup do
+ @page_class = instance_variable_get("@#{page_class}")
+ end
+
+ should "be able to unset with keys" do
+ page = @page_class.create(:title => 'Foo', :tags => %w(foo))
+ page.unset(:title, :tags)
+ assert_keys_removed @page_class, page, :title, :tags
+ end
+
+ should "be able to increment with modifier hashes" do
+ page = @page_class.create
+ page.increment(:day_count => 1, :week_count => 2, :month_count => 3)
+
+ assert_page_counts page, 1, 2, 3
+ end
+
+ should "be able to decrement with modifier hashes" do
+ page = @page_class.create(:day_count => 1, :week_count => 2, :month_count => 3)
+ page.decrement(:day_count => 1, :week_count => 2, :month_count => 3)
+
+ assert_page_counts page, 0, 0, 0
+ end
+
+ should "always decrement when decrement is called whether number is positive or negative" do
+ page = @page_class.create(:day_count => 1, :week_count => 2, :month_count => 3)
+ page.decrement(:day_count => -1, :week_count => 2, :month_count => -3)
+
+ assert_page_counts page, 0, 0, 0
+ end
+
+ should "be able to set with modifier hashes" do
+ page = @page_class.create(:title => 'Home')
+ page.set(:title => 'Home Revised')
+
+ page.reload
+ page.title.should == 'Home Revised'
+ end
+
+ should "be able to push with modifier hashes" do
+ page = @page_class.create
+ page.push(:tags => 'foo')
+
+ page.reload
+ page.tags.should == %w(foo)
+ end
+
+ should "be able to push_all with modifier hashes" do
+ page = @page_class.create
+ page.push_all(:tags => %w(foo bar))
+
+ page.reload
+ page.tags.should == %w(foo bar)
+ end
+
+ should "be able to pull with criteria and modifier hashes" do
+ page = @page_class.create(:tags => %w(foo bar))
+ page.pull(:tags => 'foo')
+
+ page.reload
+ page.tags.should == %w(bar)
+ end
+
+ should "be able to pull_all with criteria and modifier hashes" do
+ page = @page_class.create(:tags => %w(foo bar baz))
+ page.pull_all(:tags => %w(foo bar))
+
+ page.reload
+ page.tags.should == %w(baz)
+ end
+
+ should "be able to add_to_set with criteria and modifier hash" do
+ page = @page_class.create(:tags => 'foo')
+ page2 = @page_class.create
+
+ page.add_to_set(:tags => 'foo')
+ page2.add_to_set(:tags => 'foo')
+
+ page.reload
+ page.tags.should == %w(foo)
+
+ page2.reload
+ page2.tags.should == %w(foo)
+ end
+
+ should "be able to push uniq with criteria and modifier hash" do
+ page = @page_class.create(:tags => 'foo')
+ page2 = @page_class.create
+
+ page.push_uniq(:tags => 'foo')
+ page2.push_uniq(:tags => 'foo')
+
+ page.reload
+ page.tags.should == %w(foo)
+
+ page2.reload
+ page2.tags.should == %w(foo)
+ end
+
+ should "be able to pop with modifier hashes" do
+ page = @page_class.create(:tags => %w(foo bar))
+ page.pop(:tags => 1)
+
+ page.reload
+ page.tags.should == %w(foo)
+ end
+
+ should "be able to pass upsert option" do
+ page = @page_class.create(:title => "Upsert Page")
+ page.increment({:new_count => 1}, {:upsert => true})
+
+ page.reload
+ page.new_count.should == 1
+ end
+
+ should "be able to pass safe option" do
+ page = @page_class.create(:title => "Safe Page")
+
+ # We are trying to increment a key of type string here which should fail
+ assert_raises(Mongo::OperationFailure) do
+ page.increment({:title => 1}, {:safe => true})
+ end
+ end
+
+ should "be able to pass upsert and safe options" do
+ page = @page_class.create(:title => "Upsert and Safe Page")
+ page.increment({:another_count => 1}, {:upsert => true, :safe => true})
+
+ page.reload
+ page.another_count.should == 1
+ end
end
end
-
- should "be able to pass upsert and safe options" do
- page = @page_class.create(:title => "Upsert and Safe Page")
- page.increment({:another_count => 1}, {:upsert => true, :safe => true})
-
- page.reload
- page.another_count.should == 1
- end
-
end
-end
+end
Something went wrong with that request. Please try again.