Permalink
Browse files

Provide a fix for many associations not yielding to each in callbacks.

Ran into an issue when iterating over a many association in a
before_save callback on a document. For an association named foos,
`foos.inspect` would show the items but `foos.each` would never yield to
the given block since it appears to be empty.

The original issue I was tracking down was that instead of not yielding
it was yielding instances of Mongo::Cursor instead of the association
object. I haven't been able to recreate that case.
  • Loading branch information...
1 parent 73f30d9 commit 9844b2aa756f618d9c6cbe9814df07b592da84d1 @gaffneyc gaffneyc committed Oct 2, 2012
@@ -5,7 +5,7 @@ module Associations
class ManyDocumentsProxy < Collection
include DynamicQuerying::ClassMethods
- def_delegators :query, *(Querying::Methods - [:to_a, :size, :empty?])
+ def_delegators :query, *(Querying::Methods - [:each, :to_a, :size, :empty?])
def replace(docs)
load_target
@@ -71,6 +71,10 @@ def save_to_collection(options={})
@target.each { |doc| doc.save(options) } if @target
end
+ def each(&block)
+ load_target.each(&block)
+ end
+
protected
def query(options={})
klass.
@@ -35,6 +35,35 @@ def pets
instance.pets.should_not be_empty
end
+ should "be able to iterate associated documents in a callback" do
+ @owner_class.class_eval do
+ before_save :search_pets
+
+ def search_pets
+ pets.each { |p| p.name = "Animal" }
+ end
+ end
+
+ owner = @owner_class.new
+ sophie = owner.pets.build(:name => "Sophie")
+ pippa = owner.pets.build(:name => "Pippa")
+
+ owner.save
+ owner.reload
+ owner.pets.reload
+
+ pets = []
+ owner.pets.each { |p| pets << p }
+
+ assert_equal(2, pets.size)
+ assert(pets.include?(sophie))
+ assert(pets.include?(pippa))
+
+ # Weird way of testing that the callback actually interated
+ assert_equal("Animal", sophie.reload.name)
+ assert_equal("Animal", pippa.reload.name)
+ end
+
should "allow assignment of many associated documents using a hash" do
person_attributes = {
'name' => 'Mr. Pet Lover',

0 comments on commit 9844b2a

Please sign in to comment.