This project is archived and is in readonly mode.
Record Cloning Not Shallow
Reported by Paul Gillard | June 17th, 2010 @ 11:57 PM | in 3.0.2
Problem
Cloned Active Record objects receive the original object's associations.
Explanation
Roughly speaking Ruby clones objects by copying instance variables into a new object. Before #3164 Active Record implemented cloning by defining its own #clone method. This method only copied instance variables that were wanted. Since #3164 Ruby's in-built #initialize_copy gets called and this copies all instance variables. This means that associations are incorrectly copied (as they are stored within records as instance variables).
The Active Record documentation for #initialize_copy states:
Note that this is a "shallow" clone as it copies the object's attributes only, not its associations.
However this is no longer the case.
Comments and changes to this ticket
-
Paul Gillard June 18th, 2010 @ 12:16 AM
- Tag changed from patch activerecord, clone to patch activerecord, clone, patch
I attach two patches. One which clears the association cache when cloning and so returning cloning to being genuinely shallow. The other which removes an incorrect (after reading http://dev.rubyonrails.org/ticket/7191) comment added in #3164.
-
Paul Gillard June 18th, 2010 @ 05:14 PM
- Assigned user set to josh
Josh, I hope you don't mind me assigning this to you? Koz assigned a previous ticket I worked on regarding cloning to you (#3164).
-
José Valim June 21st, 2010 @ 10:42 AM
- Milestone cleared.
- Assigned user changed from josh to José Valim
-
José Valim June 21st, 2010 @ 10:44 AM
- Milestone cleared.
-
Kane June 22nd, 2010 @ 05:55 PM
Seems ticket #4733 is related, respectifely obsolete if this ticket is resolved.
Note that this is a "shallow" clone as it copies the object's attributes only, not its associations.
what does this mean for belongs_to associations? fk attribute gets cleared?
-
Repository June 23rd, 2010 @ 08:32 AM
- State changed from new to resolved
(from [d132dd33520ba61f7bfa9ba6fdd1b7b2bebd27f3]) Don't clone associations [#4894 state:resolved]
Cloning an active record object should be shallow in that it should copy attributes but not associations. This was no longer true as a result of #3164.
Signed-off-by: José Valim jose.valim@gmail.com
http://github.com/rails/rails/commit/d132dd33520ba61f7bfa9ba6fdd1b7... -
Paul Gillard June 23rd, 2010 @ 09:16 AM
The foreign key attribute doesn't get cleared just the instance variable on the object which contains the associated object. An (imagined) IRB session might be:
post = Post.first post.user_id # 1 post.instance_variable_get("@user") # nil post.user # #<User id: 1, name: "Paul"> post.instance_variable_get("@user") # #<User id: 1, name: "Paul"> clone = post.clone clone.user_id # 1 clone.instance_variable_get("@user") # nil clone.user # #<User id: 1, name: "Paul"> clone.instance_variable_get("@user") # #<User id: 1, name: "Paul"> post.clear_association_cache post.instance_variable_get("@user") # nil
-
José Valim June 23rd, 2010 @ 09:17 AM
Should I revert this current commit? Or a new patch is coming soon?
-
Paul Gillard June 23rd, 2010 @ 11:02 AM
Sorry for the confusion. My comments were simply to explain to Kane how my patch works. Its not an indication that there is a problem with the patch. I'm happy that the patch you've committed is correct and should be left as it is.
If you're happy to, could you also commit my second patch? It removes a comment I added in #3164 which is no longer relevant.
-
José Valim June 23rd, 2010 @ 11:18 AM
Paul, I forgot to tell, the second patch does not apply anymore. :(
-
Paul Gillard June 23rd, 2010 @ 09:38 PM
Second patch to remove incorrect comment re-based against master and attached.
-
Andrea Campi October 11th, 2010 @ 07:19 AM
- Tag changed from patch activerecord, clone, patch to activerecord, clone, patch
- Importance changed from to Low
bulk tags cleanup
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>
People watching this ticket
Attachments
Referenced by
- 4733 Dangerous association modifications on cloned ActiveRecord objects. #4894
- 4894 Record Cloning Not Shallow (from [d132dd33520ba61f7bfa9ba6fdd1b7b2bebd27f3]) Don't c...