views:

49

answers:

3

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

A: 

I don't know your app, but at first blush the idea of having identical data for different IDs seems a bit pointless.

In your place, I'd optimize the data structure by adding an integer count field to the data, initialized to 1. When a second (or third, ...) instance of the data pops up, just increment the counter. Same information, fewer records, less data, faster DB operation.

Carl Smotricz
In one of my apps i have a similar clone-thing (but not rails based). It's there to create some new content based on older content. Imagine Statistics that are weekly updated by hand. (eg. Stocks or the like).
Nils Riedemann
Ah, so content will start out similar but not be the same. The "clean" way would be to do this in the application and not update the DB until there is actually fresh data available, but I can understand that this might be the simplest solution. Feel free to ignore my suggestion! :)
Carl Smotricz
I thought about a counter, but it's an Inventory of items, wiith an unique Id.
benoror
+1  A: 

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.

Veger
+2  A: 

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
Simone Carletti
With Item.save! I figured out that a validation was popping out. Thanks!
benoror