What Is the Easiest Way to Duplicate an Activerecord Record

What is the easiest way to duplicate an activerecord record?

To get a copy, use the dup (or clone for < rails 3.1+) method:

#rails >= 3.1
new_record = old_record.dup

# rails < 3.1
new_record = old_record.clone

Then you can change whichever fields you want.

ActiveRecord overrides the built-in Object#clone to give you a new (not saved to the DB) record with an unassigned ID.

Note that it does not copy associations, so you'll have to do this manually if you need to.

Rails 3.1 clone is a shallow copy, use dup instead...

What is the best way to duplicate a row in Ruby on Rails

You can use dup method to do so. Like below:

old_record = Model.find(params[:id])
new_record = old_record.dup
new_record.save

How do duplicate/clone ActiveRecord::Relation in optimized way

Short answer is to use single insert statement instead of multiple inserts even though if it's in one DB transaction.

And bulk_insert gem will help you to do it. ( Thanks to arieljuod )

Clone (a.k.a. duplicate) a Record

Make sure the default cloned behavior works for you. the cloned record might actually be invalid according to your validation rules.

Try to use @item.save! instead of @item.save and check whether an exception is raised.
You can also try the code directly in a console instance.

In Console I figured out that clone generates the copy without ID.

That's true. #clone actually creates a clone but doesn't save the record.
This is why you need to call a save method in your action, which is what you actually do with

if @item.save # <-- here you save the record
flash[:notice] = 'Item was successfully cloned.'
else
flash[:notice] = 'ERROR: Item can\'t be cloned.'
end

Duplicating a record in Rails 3

If you want the clone action to allow the user to review the duplicate before it is saved (AKA created), then it is almost like the "new" action, except with filled in fields already.

So your clone method could be a modification of your new method:

def new
@prescription = Prescription.new()
end
def clone
@prescription = Prescription.find(params[:id]) # find original object
@prescription = Prescription.new(@prescription.attributes) # initialize duplicate (not saved)
render :new # render same view as "new", but with @prescription attributes already filled in
end

In the view, they can then create the object.

Create a deep copy of a record?

You may want to give the Amoeba gem a try.

Reference: https://stackoverflow.com/a/9485672/336920

Also deep_clonable.

They both work with Rails 4 and have been updated recently.

rails_to for a duplicate record

When you call #.dup on an ActiveRecord model object, which you're doing here, it copies over all attributes except for id and the base timestamps. What this means is that you have an unpersisted object. This is why you are getting the exception messages you are getting.

Assuming you want to duplicate record 678, let's say, I'd expect a path like this:

/years/new?base_id=678

In the above, base_id=678 is a query string parameter.

You'd generate it like this:

<%= link_to "Duplicate", new_year_path(base_id: @year&.id) %>

(assuming @year is initialized, of course)

Then, in your controller action:

def new
@year = Year.find_by(id: params[:base_id])&.dup || Year.new
end

Assuming we find the Year record in question, we duplicate it. Otherwise, we fall back to a new Year object and life is fine.

This should resolve your issue.

Duplicate record in Rails and populate new form with its associations

Rails does not have built-in deep cloning. In Rails 2.3.x you had clone for cloning active record attributes. In Rails >3 they renamed this method to dup, and its documentation is now missing. However, it's identical to clone and its docs say the following.

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.

So if you want to clone associations, you are on your own. In my projects I used a method called replicate for this purpose.

class User < ActiveRecord::Base
# ...
def replicate
replica = dup

comments.each do |comment|
replica.comments << comment.dup
end

replica
end
end

Something along these lines.

Make copy of record and save to database but with unique id

You need to filter out the ID from the attributes hash. ActiveSupport has a handy Hash#except method which does just this:

Blog.new(@blog.attributes.except("id"))

Additionally you may want to filter out the timestamps as well.

Copy model instances in Rails

This is what ActiveRecord::Base#clone method is for:

@bar = @foo.clone

@bar.save


Related Topics



Leave a reply



Submit