如何使用 accepts_nested_attributes_for 创建嵌套对象 [英] How to create nested objects using accepts_nested_attributes_for

查看:51
本文介绍了如何使用 accepts_nested_attributes_for 创建嵌套对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经升级到 Rails 2.3.3(从 2.1.x),我正在尝试找出 accepts_nested_attributes_for 方法.我可以使用该方法来更新现有的嵌套对象,但不能使用它来创建新的嵌套对象.鉴于人为的例子:

I've upgraded to Rails 2.3.3 (from 2.1.x) and I'm trying to figure out the accepts_nested_attributes_for method. I can use the method to update existing nested objects, but I can't use it to create new nested objects. Given the contrived example:

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

如果我尝试创建一个新的 Product,带有嵌套的 Note,如下:

If I try to create a new Product, with a nested Note, as follows:

params = {:name => 'Test', :notes_attributes => {'0' => {'body' => 'Body'}}}
p = Product.new(params)
p.save!

验证失败并显示以下消息:

It fails validations with the message:

ActiveRecord::RecordInvalid: Validation failed: Notes product can't be blank

我明白为什么会发生这种情况——这是因为 Note 类上的 validates_presence_of :product_id,并且因为在保存新记录时,Product 对象没有 id.但是,我不想删除此验证;我认为删除它是不正确的.

I understand why this is happening -- it's because of the validates_presence_of :product_id on the Note class, and because at the time of saving the new record, the Product object doesn't have an id. However, I don't want to remove this validation; I think it would be incorrect to remove it.

我也可以先手动创建Product,然后添加Note来解决这个问题,但这会破坏accepts_nested_attributes_for的简单性.

I could also solve the problem by manually creating the Product first, and then adding the Note, but that defeats the simplicity of accepts_nested_attributes_for.

是否有在新记录上创建嵌套对象的标准 Rails 方法?

Is there a standard Rails way of creating nested objects on new records?

推荐答案

这是一个常见的循环依赖问题.有一张现有的灯塔票值得一看.

This is a common, circular dependency issue. There is an existing LightHouse ticket which is worth checking out.

我希望这会在 Rails 3 中得到很大改进,但与此同时,您必须采取一种解决方法.一种解决方案是设置一个虚拟属性,您在嵌套时设置该属性以使验证有条件.

I expect this to be much improved in Rails 3, but in the meantime you'll have to do a workaround. One solution is to set up a virtual attribute which you set when nesting to make the validation conditional.

class Note < ActiveRecord::Base
  belongs_to :product
  validates_presence_of :product_id, :unless => :nested
  attr_accessor :nested
end

然后您可以将此属性设置为表单中的隐藏字段.

And then you would set this attribute as a hidden field in your form.

<%= note_form.hidden_field :nested %>

在通过嵌套表单创建注释时设置 nested 属性应该足够了.未经测试.

That should be enough to have the nested attribute set when creating a note through the nested form. Untested.

这篇关于如何使用 accepts_nested_attributes_for 创建嵌套对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆