添加现有的has_many记录与accepts_nested_attributes_for新纪录 [英] Adding existing has_many records to new record with accepts_nested_attributes_for
问题描述
该错误无法找到ID项目= 123支付与ID =添加现有项目的模型,以一种新的支付模式时出现。这是在一个的has_many关系和使用accepts_nested_attributes_for
The error "Couldn't find Item with ID=123 for Payment with ID=" occurs when adding existing Item models to a new Payment model. This is in a has_many relationship and using accepts_nested_attributes_for.
class Payment < ActiveRecord::Base
has_many :items
accepts_nested_attributes_for :items
...
class Item < ActiveRecord::Base
belongs_to :payment
...
支付和项目模型是假设性的,但问题是真实的。我需要支付的项目(像我这样的新动作)保存支付(在创建动作完成)之前关联。以用户需求为他们所创造的付款修改属性的项目(增加了计费code将是一个例子)。
The payment and item models are hypothetical but the problem is real. I need to associate the Items with the Payment (as I do in the new action) before saving the Payment (done in the create action). The user needs to modify attributes on the Items as they create the Payment (adding a billing code would be an example).
具体而言,在控制器的create动作时出现错误:
Specifically, the error occurs in the controller's create action:
# payments_controller.rb
def new
@payment = Payment.new
@payment.items = Item.available # where(payment_id: nil)
end
def create
@payment = Payment.new payment_params # <-- error happens here
...
end
def payment_params
params.require(:payment).permit( ..., [items_attributes: [:id, :billcode]])
end
的lib / active_record / nested_attributes.rb:543:!raise_nested_attributes_record_not_found在
是立即在调用堆栈在它之前。奇怪的是,ActiveRecord的是包括payment_id作为搜索条件的一部分。
lib/active_record/nested_attributes.rb:543:in 'raise_nested_attributes_record_not_found!'
is immediately prior to it in the callstack. It is curious that ActiveRecord is including payment_id as part of the search criteria.
为了被完整,形式看起来是这样的...
For the sake of being complete, the form looks something like this...
form_for @payment do |f|
# payment fields ...
fields_for :items do |i|
# item fields
和它呈现在正确的项目上的新动作。通过表单传递的PARAMS是这样的:
and it renders the Items correctly on the new action. The params passed through the form look like this:
{ "utf8"=>"✓",
"authenticity_token"=>"...",
"payment"=>{
"items_attributes"=>{
"0"=>{"billcode"=>"123", "id"=>"192"}
},
}
}
如果有更好的方式来处理这种不使用 accepts_nested_attributes_for
我很开放的建议。
If there is a better way to approach this that doesn't use accepts_nested_attributes_for
I'm open to suggestions.
推荐答案
这让我困惑...
添加现有记录到一个新的纪录。
"Adding existing records to a new record..."
所以,你必须项目1,2,3
,并希望它们关联到一个新的产品
对象?
So you have Item 1, 2, 3
, and wish to associate them to a new Product
object?
-
加入型号
要做到这一点会使用加入模型的方式
( 的habtm
),而不是通过的 accepts_nested_attributes_for
The way to do this will be to use a join model
(habtm
) rather than sending the data through accepts_nested_attributes_for
底线是每次创建一个新的产品
对象时,其相关的项目
对象可以的只有的关联到该产品:
The bottom line is every time you create a new Product
object, its associated Item
objects can only be associated to that product:
#items table
id | product_id | information | about | item | created_at | updated_at
所以,如果你想使用现有
项目
的对象,如何定义的的多个的关联又在哪里?事实是,你不能 - 你必须创建一个中间表/模型,经常被当作一个加入模型
:
So if you're looking to use existing
Item
objects, how can you define multiple associations for them? The fact is you can't - you'll have to create an intermediary table / model, often cited as a join model
:
#app/models/product.rb
Class Product < ActiveRecord::Base
has_and_belongs_to_many :items
end
#app/models/item.rb
Class Item < ActiveRecord::Base
has_and_belongs_to_many :products
end
#items_products (table)
item_id | product_id
-
HABTM
如果您使用的是HABTM设置(如我上面所演示的),它可以让你添加/从的 集合
与不同的对象有,还有一个偷偷摸摸的伎俩,你可以再补充产品
来使用某产品 item_ids
:
If you use a HABTM setup (as I have demonstrated above), it will allow you to add / delete from the collection
your various objects have, as well as a sneaky trick where you can just add Items
to a product using item_ids
:
#app/controllers/products_controller.rb
Class ProductsController < ApplicationController
def create
@product = Product.new(product_params)
@product.save
end
private
def product_params
params.require(:product).permit(item_ids: [])
end
end
如果你那么参数 item_ids []
传递给你的 create_method
,将填充集合
为您服务。
If you then pass the param item_ids[]
to your create_method
, it will populate the collection
for you.
如果你想具体的项目添加到产品
或删除它们,你不妨这样做:
If you want to add specific items to a product
, or remove them, you may wish to do this:
#app/controllers/products_controller.rb
Class ProductsController < ApplicationController
def add
@product = Product.find params[:id]
@item = Item.find params[:item_id]
@product.items << @item
@product.items.delete params[:item_id]
end
end
这篇关于添加现有的has_many记录与accepts_nested_attributes_for新纪录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!