具有多个嵌套模型的 Rails 表单会导致无线电组出现问题

Posted

技术标签:

【中文标题】具有多个嵌套模型的 Rails 表单会导致无线电组出现问题【英文标题】:Rails form with multiple nested models causes issues with radio groups 【发布时间】:2010-12-07 08:25:26 【问题描述】:

我遇到了包含单选按钮的嵌套模型表单的问题,当我有多个模型时,所有单选按钮都被视为在同一个组中。

我的模型包含这样的 has_many 关系:

class Order < ActiveRecord::Base
    has_many :order_items
    accepts_nested_attributes_for :order_items
end

Class OrderItem < ActiveRecord::Base
    belongs_to :order
end

然后我有一个部分创建 OrderItem 模型表单使用

<% fields_for "order[order_items_attributes][]", order_item do |f| %>

包含在这个表单中的是一组在 for 循环中创建的单选按钮

radio_button_tag "order[order_items_attributes][][colour_id]", "#colour.id"

当只有一个孩子时这很好用,但是一旦我插入多个孩子,所有单选按钮都属于同一组,因为它们都具有相同的属性 name="order[order_items_attributes][][colour_id]"。这都是在一个新的模型表单上,所以我不能使用数组索引(name="order[order_items_attributes][0][colour_id]"),因为 Rails 给出了错误expected Hash (got Array) for param 'order_items_attributes' 我对最后一部分的错误,错误是因为我混合了索引和非索引名称属性。添加索引值是解决这个问题的关键。

以下是仅存在一个嵌套模型时 params[:order] 哈希的内容:

"order_items_attributes"=>
  ["size"=>"Small",
    "colour_id"=>"4"],
 "first_name"=>"sdf",
 "last_name"=>"sdf",
 "email"=>"sdfg@sgf.com"

当存在两个嵌套模型时:

"order_items_attributes"=>
  ["size"=>"Small",
    "colour_id"=>"4",
   "size"=>"Small"],
 "first_name"=>"sdf",
 "last_name"=>"sdf",
 "email"=>"sdfg@sgf.com"

如您所见,只有第一个 order_item 有它的 colour_id 属性。无论所选单选按钮属于哪个型号,都会发生这种情况(这是有道理的)。

如何渲染单选按钮,以便为每个子模型创建一个单独的组?

【问题讨论】:

如果您可以粘贴 params[:order] 哈希的内容对于只有 1 个嵌套 order_item 的情况(即有效的情况)以及存在超过 1 个嵌套的 order_item(即它不起作用的情况)。对于这两个示例,在粘贴到 Stack Overflow 之前,通过漂亮的打印运行 params[:order] 哈希。 【参考方案1】:

当您调用 fields_for 时,您必须为每个订单项指定一个唯一索引。如果您以这种方式调用fields_for,则需要跟踪传递给fields_for 的数组的索引。 Rails 可以通过使用嵌套表单来为您做到这一点。

解决方案是使用嵌套表单。

<%form_for :order do |f|%>
  Form stuff for this particular order.
  If @order.order_items is empty you may need to build one before the next line.
  <%f.fields_for :order_items do |oi_f| %>
    Form stuff for this particular order_item (prefixed with oi_f.)
    <%Colour.all.each do |colour| %>
      <%=oi_f.radio_tag(:colour_id, colour.id)%>
    <%end%>
  <%end%>
<%end%>

看起来您正在发布到 orders_controller,所以这应该是替代品。

【讨论】:

谢谢,就是这样!我曾尝试使用 Firebug 手动添加索引值,但遇到了我提到的错误,原来这是因为我有其他表单字段并且混合了索引和非索引名称属性。

以上是关于具有多个嵌套模型的 Rails 表单会导致无线电组出现问题的主要内容,如果未能解决你的问题,请参考以下文章

具有活动管理员的 Rails 双嵌套表单

在 Ruby on Rails 4.2 中使用 Cocoon gem 嵌套表单

发生错误时如何在嵌套模型中填充表单?

Rails form_for 具有相同属性的嵌套和关联资源已填充文本

通过复选框Rails 4添加多个嵌套属性(可能有多种形式)

在rails 2.3+中测试(rspec)嵌套模型部分