Rails fields_for:child_index选项说明

时间:2010-05-21 02:20:51

标签: ruby-on-rails

我一直在尝试使用许多嵌套模型创建一个复杂的表单,并使其动态化。现在我发现使用accepts_nested_attributes_for制作嵌套模型并不困难,但是如果有多个嵌套模型,那么使它嵌套和动态似乎是不可能的。

我偶然发现http://github.com/ryanb/complex-form-examples/blob/master/app/helpers/application_helper.rb非常优雅。任何人都可以对13号线和16号线有所了解吗?

13 form_builder.object.class.reflect_on_association(method).klass.new

16 form_builder.fields_for(method, options[:object], :child_index => "new_#{method}") do |f|

从直觉来看,第13行实例化了一个新对象,但为什么必须这么多方法调用呢?我在第16行找不到:child_index选项的任何文档。创建表单时,非常大的数字用作新模型的索引,而现有模型则按其id编制索引。这是如何工作的?

1 个答案:

答案 0 :(得分:41)

options[:object] ||= form_builder.object.class.reflect_on_association(method).klass.new

如果对象未作为参数传递,则会创建相应类的新对象。

form_builder.object从表单(project

中获取主对象

form_builder.object.class获取其类(Project

method是项目的关联名称(:tasks

reflect_on_association(method)提供了AssociationReflection个对象。

reflect_on_association(method)。klass返回关联的类。 (Task

最后,klass.new创建了一个新实例(Task.new =>新任务)

这样做是因为关联名称并不总是像这种情况一样的多元化类名(任务 - :任务),但是必须让类对象创建它的新实例。

form_builder.fields_for(method, options[:object], :child_index => "new_#{method}") do |f|

:child_index选项允许您指定特定对象的索引:

project[tasks_attributes][:child_index][field_name]

由Rails设置为“new _#{method}”,但后来被javascript(application.js)取代:

function insert_fields(link, method, content) {
  var new_id = new Date().getTime();
  var regexp = new RegExp("new_" + method, "g")
  $(link).up().insert({
    before: content.replace(regexp, new_id)
  });
}

索引设置为大量,以免与现有项冲突。顺便说一句,它们不是id的索引,只是从0到count-1