在我的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=
有人能告诉我这里缺少什么,或者是否有更聪明的方法来复制记录包括其相关记录?
感谢您的帮助。
答案 0 :(得分: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
答案 1 :(得分: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>
我们对重复的猫有什么看法?好吧,对于初学者来说,created_at
和updated_at
都是nil
。这通常表示对象尚未保存到数据库中。如果我们去查找Cat
的{{1}},我们会注意到甚至没有专栏!
让我们尝试保存新对象。
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=
没有Invoice
,只有在未保存的情况下才会这样。
干杯!