Rails 4 表格设置 has_many 通过附加栏
Rails 4 form to set has_many through additional column
我通过一个名为 ComponentItems 的 table 在 Items 和它们的组件之间建立了 has_many 关联。除了 item_id
和 component_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
数组,根本没有任何意义。
我通过一个名为 ComponentItems 的 table 在 Items 和它们的组件之间建立了 has_many 关联。除了 item_id
和 component_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
数组,根本没有任何意义。