Rails 4 表格设置 has_many 通过附加栏

Rails 4 form to set has_many through additional column

我通过一个名为 ComponentItems 的 table 在 Items 和它们的组件之间建立了 has_many 关联。除了 item_idcomponent_id 之外,ComponentItems 还包含一列 quantity。如何在我的表格中添加一个 number_field 来显示 item 所需的每个 component 的数量?对于数据库中的每个项目,表单必须包含 number_field,即使不存在任何关系(即 @item.component_ids.empty? == true)。

class Item < ActiveRecord::Base
  has_many :components, through: :component_items
  has_many :component_items
end

class Component < Item
  has_many :items, through: :component_items
  has_many :component_items
end

class ComponentItem < ActiveRecord::Base
  belongs_to :item
  belongs_to :component
end

我相信我已经尝试了所有模型、控制器和 form_builder 可能的排列,除了正确的那个。

为了回应下面的回答,这里有一个表单,其中显示了一个复选框和构成一个特定项目的组件项目的项目代码;

<%= form_for [@item] do |f| %>
  <%= f.collection_check_boxes :component_items, Item.active.where.not(sku: @item.sku).sort_by{|n| n.sku}, :id, :sku do |b| %>
    <%= b.check_box %> <%= b.label %><br/>
   <% end %>
<% end %>

所以,理想情况下,我会将 check_box 替换为 number_field 作为数量。怎么样?

这应该有效:

@item.components.to_a.sum(&:quantity)

如果某些组件的数量为零,这将抛出错误,因此您可以这样尝试以避免错误:

@item.components.to_a.map(&:quantity).compact.sum

更新

<% @item.component_items.each do |component_item| %>
  <%= form_for(component_item) do |f| %>
    <div class="field">
      <%= f.label :quantity, 'Quantity' %><br />
      <%= f.number_field :quantity %>
    </div>
  <% end %>
<% end %>

看来我想要的毕竟不是那么简单。最后,我选择使用一些 jQuery 通过单独的表单向项目添加额外的组件。尝试 add/remove 组件并调整数量超出了我的范围,因此选择为每个用户操作使用单独的表单似乎更简单。它可能不是最人性化的工作方式,但它是我拥有的最好的方式。

要编辑数量,我执行了以下操作;

        <% @item.component_items.each do |x| %>
            <%= hidden_field_tag "item[component_items_attributes][][id]", x.id%>
            <%= label_tag x.component.sku, x.component.sku.upcase, :class=>"col-md-3 control-label" %>
            <%= number_field_tag "item[component_items_attributes][][quantity]", x.quantity, :class=>"col-md-5"%>
        <%end %>

并确保 Item 模型接受 component_items 的嵌套属性。最后,将多个 component_items 的嵌套参数数组添加到 items_controller.rb...

def item_params
    params.require(:item).permit(
      :component_items_attributes =>[:component_id, :item_id, :quantity, :id]
    )
  end

请注意,我没有使用 fields_for,它似乎生成了一个额外的 component_items_attributes 数组,根本没有任何意义。