2013-07-01 63 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