Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #7352 (closed enhancement: fixed)

Opened 1 year ago

Last modified 2 months ago

[PATCH] Add ActiveResource clone

Reported by: rwdaigle Assigned to: core
Priority: normal Milestone: 1.x
Component: ActiveResource Version: edge
Severity: normal Keywords:
Cc: thechrisoshow

Description

There's a need for the ability to clone an ARes object that knows of ARes nuances - namely that nested ARes member attributes should not be cloned with it (as that would introduce inconsistencies between prefix_options and the actual parent) and that the pk be ignored. For example:

ryan = Person.find(1)
ryan.address = Address.find(1, :person_id => ryan.id)
not_ryan = ryan.clone

# With the stock clone, the id is copied as well
not_ryan.id  # => 1

# With a stock clone, the cloned address's prefix options still point to a person
# with id = 1, which is a break from its true person which does not yet have an id
not_ryan.prefix_options  # => {:person_id => 1}

This patch introduced a clone which will both ignore the pk attribute and any member ARes attributes.

ryan = Person.find(1)
ryan.address = StreetAddress.find(1, :person_id => ryan.id)
ryan.hash = {:not => "an ARes instance"}

not_ryan = ryan.clone
not_ryan.new?            # => true (id is nil)
not_ryan.address         # => NoMethodError
not_ryan.hash            # => {:not => "an ARes instance"}

I am not sure whether this deep/shallow clone method would cause confusion (as only non-ARes member attributes are cloned, this is a deep clone with ARes exceptions) - I would welcome any feedback on the matter.

Attachments

activeresource_clone_patch.diff (3.3 kB) - added by rwdaigle on 01/24/07 16:29:41.
add ActiveResource::Base.clone
activeresource_clone_patch_updated_for_r9089.diff (3.6 kB) - added by thechrisoshow on 03/25/08 22:46:12.
Updated for r9089 (includes tests and docs)

Change History

01/24/07 16:29:41 changed by rwdaigle

  • attachment activeresource_clone_patch.diff added.

add ActiveResource::Base.clone

03/13/07 23:15:43 changed by josh

  • keywords set to verified.

07/20/07 00:50:23 changed by mpalmer

  • keywords deleted.
  • status changed from new to closed.
  • resolution set to incomplete.
  • Needs rebasing against current edge
  • I did a trivial rearrangement but the test cases still error out. I suspect that the API for ARes::Base has changed.

Please rectify these problems and reopen the ticket with an updated patch. Apart from these problems the tests and docs look good, and the implementation doesn't have any showstoppers as far as I can see from a quick look.

03/25/08 22:46:12 changed by thechrisoshow

  • attachment activeresource_clone_patch_updated_for_r9089.diff added.

Updated for r9089 (includes tests and docs)

03/25/08 22:48:11 changed by thechrisoshow

  • cc set to thechrisoshow.

03/25/08 22:48:44 changed by thechrisoshow

  • status changed from closed to reopened.
  • resolution deleted.

03/27/08 23:40:32 changed by matt

I guess I always did not_ryan.attributes = ryan.attributes

Ruby objects have 2 methods to do that, #clone and #dup "You can think of dup as being a copy of the contents and clone as being a copy of the full object. "(pragmatic programmers, Programming Ruby 2nd Edition)

I think you what you are trying to do is to create a dup method and not a clone. Also, I noticed that what you are after is already in trunk:

ryan = Person.find(1)
ryan.address = Address.find(1, :person_id => ryan.id)
not_ryan = ryan.clone

not_ryan.id  # => nil

I wish the core team had use #dup instead, but ohh well maybe my understanding of dup vs clone is just limited.

03/28/08 21:17:41 changed by bitsweat

  • status changed from reopened to closed.
  • resolution set to fixed.

(In [9121]) Add #clone. Closes #7352 [Ryan Daigle, thechrisoshow]