2013-07-01 62 views
0

我有一个表格,列中有产品行和供应商。用户可以输入每个产品/供应商组合的订单数量。处理复杂嵌套表格的最佳方法

enter image description here

对于每个供应商,创建1阶。每个订单都包含OrderItems。 OrderItems是为用户输入数量的每个字段(产品/供应商组合)创建的。

有很多手写代码来处理提交的表单。

有没有什么办法干掉下面的任何代码? 或者还有更好的方法吗?

我检出了嵌套表格Railscast,但我没有看到任何方式,因为输入是二维的(供应商和产品的组合),因此我可以在这里使用accept_nested_attributes_for。

class Product < ActiveRecord::Base  
    has_many :order_items 
end 

class Supplier < ActiveRecord::Base  
    has_many :orders 
end 

# groups all OrderItems for 1 Supplier 
class Order < ActiveRecord::Base  
    has_many :order_items 
    belongs_to :supplier 

    def self.create_orders_and_order_items(orders)    
    orders.each do |supplier_id, order_items| 
     if order_has_order_item?(order_items) 
     order = create!(
      :total => 0, 
      :supplier_id => supplier_id, 
      :order_group_id => order_group.id 
     )   
     OrderItem.create_order_items(order, order_items)     
     # update attributes 
     order.update(:total => order.order_items.sum(:total))   
     end  
    end 
    end 

    def self.order_has_order_item?(order_items) 
    sum = 0 
    order_items.each do |product_id, quantity| 
     sum += quantity.to_i 
    end 
    sum > 0 ? true : false  
    end  
end 

# 1 OrderItem per product/supplier combination 
class OrderItem < ActiveRecord::Base  
    belongs_to :order 
    belongs_to :supplier 
    belongs_to :product 

    def self.create_order_items(order, order_items)   
    order_items.each do |product_id, quantity| 
     if quantity.to_i > 0       
     order_item = create!(
      :quantity => quantity, 
      :product_id => product_id, 
      :order_id => order.id, 
     ) 

     # update after creating, because methods called below are only available once object has been instantiated 
     order_item.udpate(:total => order_item.calculate_total) 
     end 
    end 
    end 
end 

class OrdersController < ApplicationController 
    def create 
    Order.create_orders_and_order_items(params[:orders]) 
    respond_to do |format| 
     format.html { redirect_to :action => "index" } 
    end 
    end 
end 

# view: _form.html.erb 
<table> 
    <tr> 
    <td>Name</td> 
    <% @suppliers.each do |supplier| %> 
     <td COLSPAN=2><%= supplier.name %></td> 
    <% end %> 
    </tr> 
    <% @products.each do |product| %> 
    <tr> 
     <td><%= product.name %></td> 
     <td><%#= some price %></td> 
     <td><%= f.text_field "#{supplier.id}[#{product.id}]", :value => "" %></td> 
    </tr> 
</table> 

<%= f.submit %> 

# params (from memory) 
{"orders" => { 
    "4" => # supplier_id, 1 Order for each Supplier 
    { "13" => "2" } # product_id => quantity, = 1 OrderItem 
    } 
} 
+0

在哪里你需要嵌套的属性,我看到一个表格有几个字段的顺序。我想你是添加OrderItem到一个订单,对吧? – juanpastas

+0

嗯你循环所有'@产品'是这些OrderItems,我想不是。 – juanpastas

+0

是的,我将OrderItems添加到每个订单。不,产品不是OrderItems。该表格列出产品。 OrderItems是在供应商/产品组合的数量为!= nil的情况下创建的。 – migu

回答

1

遍历所有的产品似乎并不应该在这种情况下做什么。我会在Order模型中添加accepts_nested_attributes_for

这会让你删除你的create_orders_and_order_itemscreate_order_items

此外,我会在OrderItem模型中使用validation for quantity

我不确定您的代码是否如此工作:您进入您的页面并查看所有产品的列表,然后您可以为每个产品输入数量。

取而代之,您应该有可添加/可移动的条目,并且在每个条目中允许用户选择产品和数量。这是通过accepts_nested_attributes_for完成的,您的方式可以通过nested_form来实现。

+0

不知道数量验证,感谢您的链接和帖子。 – migu