Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Record Cloning Not Shallow

#4894

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.

Reported by Paul Gillard · June 17th, 2010 @ 11:57 PM

State: resolved
Milestone: 3.0.2
Assigned to: José Valim José Valim
Importance: Low

Activity

  1. Paul Gillard
    Paul Gillard
    • 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.

    June 18th, 2010 @ 12:16 AM

  2. Paul Gillard
    Paul Gillard
    • 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).

    June 18th, 2010 @ 05:14 PM

  3. José Valim
    José Valim
    • Milestone cleared.
    • Assigned user changed from josh to José Valim

    June 21st, 2010 @ 10:42 AM

  4. José Valim
  5. Kane
    Kane

    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?

    June 22nd, 2010 @ 05:55 PM

  6. Repository
    Repository
    • 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...

    June 23rd, 2010 @ 08:32 AM

  7. Paul Gillard
    Paul Gillard

    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
    

    June 23rd, 2010 @ 09:16 AM

  8. José Valim
    José Valim

    Should I revert this current commit? Or a new patch is coming soon?

    June 23rd, 2010 @ 09:17 AM

  9. Paul Gillard
    Paul Gillard

    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.

    June 23rd, 2010 @ 11:02 AM

  10. José Valim
    José Valim

    Paul, I forgot to tell, the second patch does not apply anymore. :(

    June 23rd, 2010 @ 11:18 AM

  11. Paul Gillard
    Paul Gillard

    Second patch to remove incorrect comment re-based against master and attached.

    June 23rd, 2010 @ 09:38 PM

  12. José Valim
    José Valim

    FYI: the patch above was already applied. :)

    June 24th, 2010 @ 09:31 PM

  13. Andrea Campi
    Andrea Campi
    • Tag changed from patch activerecord, clone, patch to activerecord, clone, patch
    • Importance changed from to Low

    bulk tags cleanup

    October 11th, 2010 @ 07:19 AM

  14. Jeremy Kemper
  15. Ryan Bigg
    Ryan Bigg
    • Tag cleared.

    Automatic cleanup of spam.

    October 21st, 2010 @ 03:35 AM