Rails 4表单通过附加列设置has_many

时间:2016-06-06 18:52:30

标签: ruby-on-rails ruby-on-rails-4 has-many-through

我通过名为ComponentItems的表在项目及其组件之间建立了一个has_many关联。除了quantityitem_id之外,ComponentItem还包含一列component_id。如何在我的表单中添加一个number_field,以显示component所需的每个item的数量?即使没有关系(即@item.component_ids.empty? == true),表单也必须包含数据库中每个Item的number_field。

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

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

2 个答案:

答案 0 :(得分:1)

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

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

        <% @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的嵌套params数组添加到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数组。

答案 1 :(得分:0)

这应该有效:

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