Ben Orozco
Ben Orozco

Reputation: 4381

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

I need to duplicate a record, with the same attributes of the original except ID of cource. I do:

In the View:

<%= link_to "Duplicate", :action => "clone", :id => Some_Existing_ID %>

And in the Controller:

def clone
  @item = Item.find(params[:id]).clone

  if @item.save
    flash[:notice] = 'Item was successfully cloned.'
  else
    flash[:notice] = 'ERROR: Item can\'t be cloned.'
  end

  redirect_to(items_path)
end      

But nothing happens! In Console I figured out that clone generates the copy without ID.

Any ideas ?

*> BTW: I am running Rails 2.3.5 and Ruby 1.8

Upvotes: 6

Views: 8624

Answers (3)

Hendrik
Hendrik

Reputation: 4929

Avoid using the clone method. It is no longer supported. The clone method now delegates to using Kernel#clone which will copy the id of the object.

# rails < 3.1
new_record = old_record.clone

# rails >= 3.1
new_record = old_record.dup

Upvotes: 7

Simone Carletti
Simone Carletti

Reputation: 176362

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

Upvotes: 3

Veger
Veger

Reputation: 37906

In the script/console this works for me

>> i = Item.find(:first)
=> #<Item id: 1, name: "Item 1", description: "This is item 1!", created_at: "2010-01-03 21:51:49", updated_at: "2010-01-05 18:25:42">
>> i2 = i.clone
=> #<Item id: nil, name: "Item 1", description: "This is item 1!", created_at: "2010-01-03 21:51:49", updated_at: "2010-01-05 18:25:42">
>> i2.save
=> true
>> i2
=> #<Item id: 2, name: "Item 1", description: "This is item 1!", created_at: "2010-01-03 21:51:49", updated_at: "2010-01-05 18:25:42">

The cloning indeed do not increment the id field (logical since this is a database action). After saving the item, the id now is updated and my database contains the clone.

So it should work... You could try this in you console as well, to see whether this works as well or it is failing like your example. You also can split the first line, so find the original and clone it into a new variable and print (logger.debug @item.inspect) both to the console to see whether the cloning succeeded. Also print the cloned item after saving to see, whether things got changed or not.

Upvotes: 2

Related Questions