Reputation: 387
When a user updates an invoice form, i want to create a new invoice record with the updated attributes, but also change one or two fields of the old record and save it, too.
How would the outline of a controller action look like which could accomplish this?
Upvotes: 0
Views: 100
Reputation: 387
Nested attributes made things a bit tricky. So in order to create new instances I had to use the dup
method for both the resource and its nested items.
Generally, it is advisable to keep the controllers slim and make the models fat. Nevertheless, I have decided to include this code into my Invoices controller:
def revise_save
@contact = Contact.find(params[:contact_id])
@invoice = @contact.invoices.find(params[:invoice_id])
@invoice_old = @invoice.dup
@invoice.invoice_items.each do |item|
@invoice_old.invoice_items << item.dup
end
@invoice.datum = DateTime.now.to_date
# archive old invoice
# @invoice_old. ...
@invoice_old.save
# make old new invoice
@invoice.datum = Time.now
# ...
@invoice.update(invoice_params)
redirect_to invoices_path
end
Note that in this solution the currently edited (original) invoice becomes the new invoice, the old one is paradoxically created anew.
Thanks to @iwan-b for pointing me in the right direction.
Upvotes: 0
Reputation: 2339
I am rather new with Rails but this seems pretty straightforward. As you mention the user is 'updating" an invoice, your controller view has probably been passed all the data available to the user for further change.
When submitting the form, your update action can easily update the current record data, as well as creating a new one on top of this
Though as it is automated, you need to make clear:
Upvotes: 1
Reputation: 4166
Instead of a controller action i put the code in the model, using callbacks:
before_save do |rec|
if !rec.new_record?
attrb = rec.attributes.delete_if{|k, v| ["id"].include? k }
Book.create(attrb)
rec.restore_attributes
rec.year = rec.year + 2 # some custom change
true
end
end
I keep all attributes unless the 'id' (otherwise i get an error) for create a new record with the new attributes. Then i restore the attributes of the existing record. I do some custom change before saving.
Upvotes: 1