IAm*_*NaN 7 activerecord ruby-on-rails ruby-on-rails-4
将现有项模型添加到新的付款模型时,会出现错误"无法找到ID = 123的项目,ID = 123".这是一个has_many关系并使用accepts_nested_attributes_for.
class Payment < ActiveRecord::Base
has_many :items
accepts_nested_attributes_for :items
...
class Item < ActiveRecord::Base
belongs_to :payment
...
Run Code Online (Sandbox Code Playgroud)
付款和项目模型是假设的,但问题是真实的.在保存付款(在创建操作中完成)之前,我需要将项目与付款关联(就像我在新操作中一样).用户在创建付款时需要修改项目的属性(添加帐单代码就是一个例子).
具体来说,错误发生在控制器的创建操作中:
# 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
Run Code Online (Sandbox Code Playgroud)
lib/active_record/nested_attributes.rb:543:in 'raise_nested_attributes_record_not_found!'紧接在callstack之前.很奇怪ActiveRecord包含payment_id作为搜索条件的一部分.
为了完整,表单看起来像这样......
form_for @payment do |f|
# payment fields ...
fields_for :items do |i|
# item fields
Run Code Online (Sandbox Code Playgroud)
并在新操作上正确呈现项目.通过表单的params看起来像这样:
{ "utf8"=>"?",
"authenticity_token"=>"...",
"payment"=>{
"items_attributes"=>{
"0"=>{"billcode"=>"123", "id"=>"192"}
},
}
}
Run Code Online (Sandbox Code Playgroud)
如果有更好的方法来解决这个问题,那么accepts_nested_attributes_for我就不会接受建议.
ste*_*ser 13
我只是item_ids在params中添加了一个集合(除了之外items_attributes).您应该能够在控制器中按下您的参数,看起来像这样
{ "utf8"=>"?",
"authenticity_token"=>"...",
"payment"=>{
"item_ids"=>[192]
"items_attributes"=>{
"0"=>{"billcode"=>"123", "id"=>"192"}
},
}
}
Run Code Online (Sandbox Code Playgroud)
更新1:由于某种原因,这只有在哈希item_ids之前才有效items_attributes.尚未审查Rails文档尚未找出原因.
这让我很困惑...
“将现有记录添加到新记录中...”
那么您有Item 1, 2, 3,并希望将它们关联到一个新Product对象?
--
加盟模式
执行此操作的方法是使用join model(habtm ) 而不是通过发送数据accepts_nested_attributes_for
最重要的是,每次创建一个新Product对象时,其关联Item对象只能该产品关联:
#items table
id | product_id | information | about | item | created_at | updated_at
Run Code Online (Sandbox Code Playgroud)
因此,如果您想要使用existing Item对象,如何为它们定义多个关联?事实是你不能 - 你必须创建一个中间表/模型,通常被引用为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
Run Code Online (Sandbox Code Playgroud)
--
HABTM
如果您使用 HABTM 设置(正如我上面所演示的),它将允许您从各种对象中添加/删除collection,以及一个偷偷摸摸的技巧,您可以Items使用以下命令添加到产品中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
Run Code Online (Sandbox Code Playgroud)
如果您随后将参数传递item_ids[]给您的create_method,它将填充collection。
如果您想向 中添加特定项目product或删除它们,您可能希望这样做:
#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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4024 次 |
| 最近记录: |