ActiveRecord::Base already has an implementation of a “shallow” clone. From it’s documentation:
# Returns a clone of the record that hasn't been assigned an id yet and # is treated as a new record. Note that this is a "shallow" clone: # it copies the object's attributes only, not its associations. # The extent of a "deep" clone is application-specific and is therefore # left to the application to implement according to its need.
And this implementation is fine by default. However, in a few application I’ve seen myself writing the same deep-clone code over and over again. When I take a look at all those implementations, my needs are quite the same most of the time, cloning some associations, and excluding (clearing) some attributes.
For this I’ve written the DeepClone plugin, which allows you to do just that, including associations and excluding attributes. A real-life example:
class Invoice < ActiveRecord::base has_many :invoice_items belongs_to :client def to_param iid # InvoiceID, eg IV08002 end end
The application needed a way to copy an invoice, including all it’s invoiceitems, but not the iid, or the clientid. The plugin makes this really easy.
@invoice = Invoice.find_by_iid('IV08001') @new_invoice = @invoice.clone :include => :invoice_items, :except => [:iid, :client_id]
Which does exactly what I need. The plugin repository can be found at http://github.com/openminds/deep_cloning/tree/master
When you’re on Rails Trunk, you can install the plugin with:
script/plugin install git://github.com/openminds/deep_cloning.git