I would like to
1. Grab an object 1 and object 2 from the database (both have 2 has_many associations each)
2. Create object 3 which is a clone of object 1 and therefore has no associations yet
2. Duplicate object 2’s associations and add them to object 3’s associations
3. Use the new object 3 for operations in memory
4. Exit the process with no permanent change to the database – object 1 and object 2 still have their original associations when the process exits
What instead is happening
- I grab an object 1 and object 2 from the database (both have 2 has_many associations each)
- I create object 3 which is a clone of object 1 and therefore has no associations yet
- I duplicate object 2’s associations and add them to object 3’s associations
- I use the new object 3 for operations in memory
- I exit the process HOWEVER there is now a permanent change to the database – object 2 no longer has its associations because their keys have been changed to the (Temporary) object 3 id.
Here is my code. Note that all contains an array with an arbitrary # of objects in it
object1 = all.last.clone #we take the most recently created object
all.each do |instance|
instance_association1 = (instance.association1).dup
object1.association1 += instance_association1 #BUG this moves the association
object1.association1.uniq!
instance_association2 = (instance.association2).dup
object1.association2 += instance_association2
object1.association2.uniq!
end
Note that now when I say:
all.last.association1, I get an empty array.
Help!!
MongoMapper’s associations may be a little overzealous with saving. I want to overhaul it sometime, but it’s not an easy problem.
The code that’s going to tell you when saves happen is many_documents_proxy.rb. When you do
my_association = [...],replaceis the method that’s called.The only method that doesn’t do any saving is
build, so you may be able to build up your temporary object like so:More generally, you can convert all your associated documents to arrays and not worry about saving…
HOWEVER, watch out! Ruby’s
uniqmethod looks like it uses Ruby’s#hashmethod to compute equality, which may not give you the results you want in this case. Do a few tests to make sure thatmy_obj.hash == my_obj2.hashifmy_obj == my_obj2. See this discussion for strategies on implementing your own#hashmethod, if that’s the route you need to go.