Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to duplicate a record and its associated records in Ruby on Rails?

In my Rails app I have invoices and their associated items.

In my InvoicesController I added this method:

def duplicate
  invoice = Invoice.find(params[:id])
  @invoice = invoice.dup
  invoice.items.each do |item|
    @invoice.items << item
  end      
  render :new    
end

def create
  @invoice = current_user.invoices.build(params[:invoice])    
  if @invoice.save
    flash[:success] = "Invoice created."
    redirect_to edit_invoice_path(@invoice)
  else
    render :new
  end
end

Clicking the link instantiates a form with the correct invoice and items data.

However, when trying to Create the record I get an error:

Couldn't find Item with ID=4 for Invoice with ID=

Can anybody tell me what I am missing here or if there's a smarter way to duplicate a record including its associated records?

Thanks for any help.

like image 700
Tintin81 Avatar asked Oct 27 '25 06:10

Tintin81


1 Answers

Here's cose that will duplicate the main object, and each of the items underneath it. The new object will not be saved, nor will the items (yet).

  def duplicate
    dup.tap do |new_invoice|
      items.each do |item|
        new_invoice.items.push item.dup
      end
    end
  end

And a quick test to prove the things:

require 'test_helper'

class InvoiceTest < ActiveSupport::TestCase

  def original_invoice
    Invoice.create(number: 5).tap do |invoice|
      invoice.items.create(name: "a", price: "5")
      invoice.items.create(name: "b", price: "50")
    end
  end
  test "duplication" do
    new_invoice = original_invoice.duplicate
    new_invoice.save
    assert_equal 2, new_invoice.items.count
  end
end
like image 127
Jesse Wolgamott Avatar answered Oct 29 '25 21:10

Jesse Wolgamott