如何使用fields_for“parents []”获取正确的子ID,父对象| f |使用f.fields_for:孩子,孩子?

时间:2011-06-24 23:56:11

标签: ruby-on-rails-3 fields-for

我正在一个表单的索引视图中编辑父模型的多个实例,如Railscasts#198。 每个父母has_many:children和accepts_nested_attributes_for:children,如Railscasts#196和#197

<%= form_tag %>
  <% for parent in @parents %>
    <%= fields_for "parents[]", parent do |f|
      <%= f.text_field :job %>
      <%= f.fields_for :children do |cf| %>
         <% cf.text_field :chore %>
      <% end %> 
    <% end %> 
  <% end %> 
<% end %>  

鉴于parent.id == 1
f.text_field:作业正确生成

<input id="parents_1_job" type="text" value="coding" size="30" name="parents[1][job]">  

但是cf.text_field:chore生成没有父索引的id和名称。

id="parents_children_attributes_0_chore"  
name="parents[children_attributes][0][chore]"    

如果我尝试将特定子对象传递给f.fields_for,如下所示:

<% for child in parent.children %>
  <%= f.fields_for :children, child do |cf| %>
    <%= cf.text_field :chore %>
  <% end %>
<% end %>  

我也一样。如果我改变方法:从孩子到“[]孩子”我得到了

id =“parents_1 ___ children_chore”

获取正确的parent_index,但不为子索引提供数组槽。

“[]孩子[]”也不对:   ID = “parents_1__children_3_chore”

因为我期待的是attributes_0_chore而不是3_chore。

我是否需要直接修改FormBuilder对象的属性,或者使用FormBuilder的子类来使其工作,或者是否存在适合这种情况的语法?

感谢您的任何想法。

1 个答案:

答案 0 :(得分:6)

我通过阅读FormBuilder.fields_for

的源代码解决了这个问题

一个可能的答案:是的,修改FormBuilder对象的f.object_name属性。

特别是在这种情况下

f.fields_for :children  

将打电话

f.fields_for_with_nested_attributes

根据f.object_name设置名称变量。生成的元素的id看起来像是基于名称,因此两者都匹配生成的html。

def fields_for_with_nested_attributes(association_name, args, block)
      name = "#{object_name}[#{association_name}_attributes]"
.....

因此,告诉f.fields_for执行我想要的操作的一种方法是将f.object_name设置为包含f.fields_for块持续时间的父ID

<% old_object_name = f.object_name %>
<% f.object_name="parents[#{f.object.id}]" %>
<% =f.fields_for :children do |cf| %>
  <%= cf.text_field :chore %>
<% end %>
<% f.object_name=old_object_name #should be "parents[]" %>

然后f.fields_for块中的所有内容都可以使用未经修改的标准rails助手。