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

发布于 2024-11-17 11:38:11 字数 1408 浏览 4 评论 0原文

我正在以一种形式在索引视图中编辑父模型的多个实例,如 Railscasts #198 中所示。 每个父节点 has_many :children 并接受_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 :job 正确生成

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

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

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 %>  

我得到相同的结果。如果我将方法从 :children 更改为 "[]children" 我会得到

id="parents_1___children_chore"

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

“[]children[]”也不正确: id="parents_1__children_3_chore"

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

我是否需要直接修改 FormBuilder 对象的属性或子类 FormBuilder 才能完成此工作,或者是否有适合这种情况的语法?

感谢您的任何想法。

I'm editing multiple instances of a parent model in an index view in one form, as in Railscasts #198.
Each parent has_many :children and accepts_nested_attributes_for :children, as in Railscasts #196 and #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 %>  

Given parent.id==1
f.text_field :job correctly generates

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

But cf.text_field :chore generates ids and names that don't have the parent index.

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

If I try passing the specific child object to f.fields_for like this:

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

I get the same. If I change the method from :children to "[]children" I get

id="parents_1___children_chore"

which gets the right parent_index but doesn't provide an array slot for the child index.

"[]children[]" isn't right either:
id="parents_1__children_3_chore"

as I was expecting attributes_0_chore instead of 3_chore.

Do I need to directly modify an attribute of the FormBuilder object, or subclass FormBuilder to make this work, or is there a syntax that fits this situation?

Thanks for any thoughts.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你怎么这么可爱啊 2024-11-24 11:38:11

我确实通过阅读 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 助手。

I did solve this problem by reading the source code for FormBuilder.fields_for

One possible answer: Yes, modify the f.object_name attribute of the FormBuilder object.

Specifically in this situation

f.fields_for :children  

is going to call

f.fields_for_with_nested_attributes

which sets the name variable based on f.object_name. The id for the generated element looks like it is based on the name,so both match in the resulting html.

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

So one way to tell f.fields_for to do what I wanted is to set f.object_name to include the parent id for the duration of the f.fields_for block

<% 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[]" %>

Then everything within the f.fields_for block can use the standard rails helpers unmodified.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文