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
Restarting a Loop from the Top
Find Out If Current Time Is Between Two Times
How to Assign a Variable in an If Else Statment Check
How to Check If a Value Exists in an Array in Ruby
To_D to Always Return 2 Decimals Places in Ruby
How to Reload the Current Page in Ruby on Rails
How to Uninstall Ruby Installed by Ruby-Install
Error: While Executing Gem ... (Gem::Filepermissionerror)
Validation for Non-Negative Integers and Decimal Values
Regex for Checking the Last Character
How to Call Shell Commands from Ruby
Is There Any Difference Between the ':Key =≫ "Value"' and 'Key: "Value"' Hash Notations
How to Dynamically Create a Local Variable
Ssl_Connect Returned=1 Errno=0 State=Sslv3 Read Server Certificate B: Certificate Verify Failed