0

让我们考虑一下 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 %>

问题是在我的情况下,我有一个完整的常量表products,其中包含预定义的产品集。我需要在订单的创建/编辑视图上显示所有产品列表,并且用户应该设置他需要的每种产品的数量,没有办法添加额外的产品。order_products是一个连接表。

在经典示例中,用户可以自己在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}}
4

1 回答 1

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
于 2013-08-27T20:08:15.257 回答