如何使用accepts_nested_attributes_for创建嵌套对象
我已升级到Rails 2.3.3(从2.1.x开始),我正在尝试找出accepts_nested_attributes_for
方法。 我可以使用该方法更新现有的嵌套对象,但我无法使用它来创建新的嵌套对象。 鉴于人为的例子:
class Product < ActiveRecord::Base has_many :notes accepts_nested_attributes_for :notes end class Note < ActiveRecord::Base belongs_to :product validates_presence_of :product_id, :body end
如果我尝试使用嵌套Note
创建新Product
,如下所示:
params = {:name => 'Test', :notes_attributes => {'0' => {'body' => 'Body'}}} p = Product.new(params) p.save!
它使用以下消息validation失败:
ActiveRecord::RecordInvalid: Validation failed: Notes product can't be blank
我理解为什么会发生这种情况 – 这是因为Note
类上的validates_presence_of :product_id
,并且因为在保存新记录时, Product
对象没有id
。 但是,我不想删除此validation; 我认为删除它是不正确的。
我也可以通过首先手动创建Product
,然后添加Note
来解决问题,但这会破坏accepts_nested_attributes_for
的简单性。
是否有标准的Rails方法在新记录上创建嵌套对象?
这是一个常见的循环依赖问题。 现有的LightHouse门票值得一试。
我希望在Rails 3中有很大的改进,但与此同时你必须做一个解决方法。 一种解决方案是设置嵌套时设置的虚拟属性,以使validation成为条件。
class Note < ActiveRecord::Base belongs_to :product validates_presence_of :product_id, :unless => :nested attr_accessor :nested end
然后,您将此属性设置为表单中的隐藏字段。
<%= note_form.hidden_field :nested %>
这应该足以在通过嵌套表单创建注释时设置nested
属性。 未经测试。
如果您使用Rails3,请检查此文档。
Ryan的解决方案实际上非常酷。 我去了,让我的控制器更胖,这样就不必在视图中出现这种嵌套了。 主要是因为我的观点有时是json,所以我希望能够在那里尽可能少地逃脱。
class Product < ActiveRecord::Base has_many :notes accepts_nested_attributes_for :note end class Note < ActiveRecord::Base belongs_to :product validates_presence_of :product_id unless :nested attr_accessor :nested end class ProductController < ApplicationController def create if params[:product][:note_attributes] params[:product][:note_attributes].each { |attribute| attribute.merge!({:nested => true}) } end # all the regular create stuff here end end
最好的解决方案是使用parental_control插件: http : //github.com/h-lame/parental_control