3

在我的 Rails 应用程序中,我拥有invoices及其关联的items.

在我的InvoicesController我添加了这个方法:

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

invoice单击该链接将使用正确的items数据实例化一个表单。

但是,在尝试Create记录时出现错误:

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

谁能告诉我我在这里遗漏了什么,或者是否有更聪明的方法来复制记录,包括其相关记录?

谢谢你的帮助。

4

2 回答 2

2

这是复制主对象及其下面的每个项目的 cose。新对象将不会被保存,项目(还)也不会。

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

并进行快速测试以证明事情:

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
于 2013-06-09T18:20:29.950 回答
1

让我们从您的错误消息开始稍微解构一下。

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

现在,乍一看,人们可能会认为没有 ID 为 4 的项目。这是一个很好的健全性检查,以确保像这样的简单事情不是问题。在这种情况下,我们有适当的项目,所以我们可以继续。

起初让我感到奇怪的是没有数字追随者ID=。事实证明,这暗示了问题所在。

让我们看看一些控制台输出。我将使用 Cat 对象,仅仅是因为它们很棒。

我们要做的第一件事是得到一只猫:

Cat.first
=> Cat Load (0.2ms)  SELECT "cats".* FROM "cats" LIMIT 1
=> #<Cat id: 2, age: 6, birthdate: "2013-06-08", color: "brown", name: "Aaron", gender: "m", created_at: "2013-06-08 21:44:22", updated_at: "2013-06-08 21:44:22", user_id: 1> 

有了猫之后,让我们复制它。

Cat.first.dup
Cat Load (0.3ms)  SELECT "cats".* FROM "cats" LIMIT 1
=> #<Cat age: 6, birthdate: "2013-06-08", color: "brown", name: "Aaron", gender: "m", created_at: nil, updated_at: nil, user_id: 1> 

关于复制的猫,我们注意到了什么?好吧,对于初学者来说,bothcreated_atupdated_atare nil。这通常表明该对象尚未保存到数据库中。如果我们去寻找Cat's ID,我们会注意到它甚至没有一列!

让我们尝试保存新对象。

Cat.first.dup.save
Cat Load (0.3ms)  SELECT "cats".* FROM "cats" ORDER BY "cats"."id" DESC LIMIT 1
(0.1ms)  begin transaction
SQL (0.7ms)  INSERT INTO "cats" ("age", "birthdate", "color", "created_at", "gender", "name", "updated_at", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?, ?)  [["age", 6], ["birthdate", Sat, 08 Jun 2013], ["color", "brown"], ["created_at", Sun, 09 Jun 2013 18:10:47 UTC +00:00], ["gender", "m"], ["name", "Aaron"], ["updated_at", Sun, 09 Jun 2013 18:10:47 UTC +00:00], ["user_id", 1]]
(0.7ms)  commit transaction
=> true 

现在,如果我们调用Cat.last,它将返回这个对象。

Cat.last
Cat Load (0.3ms)  SELECT "cats".* FROM "cats" ORDER BY "cats"."id" DESC LIMIT 1
=> #<Cat id: 11, age: 6, birthdate: "2013-06-08", color: "brown", name: "Aaron", gender: "m", created_at: "2013-06-09 18:10:47", updated_at: "2013-06-09 18:10:47", user_id: 1> 

您的问题是,当您复制 时Invoice,您没有将其保存到数据库中。Couldn't find Item with ID=4 for Invoice with ID=证实了这一点,因为它告诉我们重复的Invoicehas no ID,只有在没有保存的情况下才会出现这种情况。

干杯!

于 2013-06-09T18:13:56.377 回答