让我们考虑一下Rails中多对多模型的经典实现。
class Order
has_many :order_products
has_many :products, through: order_products
accepts_nested_attributes_for :order_products
end
class Product
has_many :order_products
has_many :orders, through: order_products
end
class OrderProduct
belongs_to :order
belongs_to :product
accepts_nested_attributes_for :products
end
<%= form_for(@order) do |f| %>
<% f.fields_for :order_products do |op|%>
<%= op.label :amount %><br>
<%= op.text_field :amount %>
<% op.fields_for :product do |p|%>
<%= p.label :name %><br>
<%= p.text_field :name %>
<% end %>
<% end %>
问题出在我的情况下,我有一个完整的常数表产品,带有预定义的产品组。我需要在订单的创建/编辑视图中显示产品的所有列表,并且用户应设置他需要的每个产品的数量,无法添加其他产品。 order_products 是一个联接表。
在经典示例中,用户可以自己添加/删除产品到产品表,在我的情况下,他只能从预定义的集合中选择所需的产品,并且他的选择应记录在 order_products中表。
以上代码是针对经典案例给出的,我不知道如何将其与我的案例相符。
感谢您的帮助。
附录: 以下是我现在的代码
<%= form_<%= form_for(@order) do |f| %>
<% f.fields_for :order_products do |op|%>
<%= op.label :amount %><br>
<%= op.text_field :amount %>
<%= op.label :product_id, "Product" %>
<%= op.select :product_id, Product.all.collect { |p| [p.name, p.id] } %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
我必须将以下代码添加到订单控制器中,以便创建所有未包含的产品以订购0金额,以便所有这些产品都在表单上。这不是最好的方法,你知道如何正确地做到这一点吗?
Product.all.each { |p| order.orderproducts.push(OrderProduct.new(:product_id => p.id,:order_id => 1, :amount => 0)) if !@order.orderproducts.any?{|b| b.product_id == p.id}}
答案 0 :(得分:2)
好像您需要amount
上的OrderProduct
列/属性,并且您可以删除该类上的嵌套产品声明。
然后,您可以从订单中创建OrderProduct
个实例,指定您想要的产品和该产品的数量。您不需要任何产品嵌套,因为您已经创建了产品。
然后你的表格会变成:
<%= form_for(@order) do |f| %>
<% f.fields_for :order_products do |op|%>
<%= op.label :amount %><br>
<%= op.text_field :amount %>
<%= op.label :product_id, "Product" %>
<%= op.select :product_id, Product.all.collect { |p| [p.name, p.id] } %>
<% end %>
还应该为OrderProduct
添加验证,以确保amount
是有效的,正整数。
validates_numericality_of :amount,
:only_integer => true,
:greater_than_or_equal_to => 0