2010-01-27 56 views
0

我正在基於敏捷Web開發使用Rails(版本3)創建購物車。我已經設置了將「商品」添加到「購物車」的位置,然後在開始結帳流程時,它們將作爲「line_items」添加到「訂單」對象中。 「line_items」代表任何數量的一個「項目」。到目前爲止,我沒有偏離書中的例子。但是,這裏是對我而言變得複雜的地方。我商店中的每個「商品」都可以使用文字進行自定義,並且我需要能夠在「訂單」中使用「line_items」來存儲自定義文字。多個模型的導軌結帳形式

如上所述,「line_items」包含任何數量的「item」,但客戶需要能夠自定義每個項目,因此每個「line_item」必須爲每個「item」項目保留不同的自定義設置。 。因此,「line_items」表中不能只有一列用於自定義。我決定組織它的方式是創建一個新的模型/表「line_item_attributes」。對於「line_item」中的每個「item」,都有一個新的「line_item_attributes」。

我對Rails還很新,而且在解決這個問題上遇到了一些麻煩。我不相信我甚至是這樣做的「正確的方式」。我碰到的是一種雞/雞蛋問題。當我創建「訂單」時,我將購物車中的「商品」添加爲「line_items」。現在爲了自定義他們訂購的產品,我還需要爲每個「line_item」添加「line_item_attributes」,以便定製表單可以使用。

以下是我不知道的:我不知道如何在客戶提交表單後「填寫」空白的「line_item_attributes」。我無法爲表單創建「虛擬」line_item_attributes,然後從提交的數據中提交創建新的(實際上將保存的)。這是因爲它們必須與他們所屬的「line_items」綁定。我希望Rails能夠在我稱爲「@ order.save」時填充它們,但事實並非如此。我希望這不是很難理解。

我已經包括相關代碼如下:

buy.rb(控制器)

-SNIP- 
def purchase 
    @cart = find_cart 

    if @cart.items.empty? 
    redirect_to_index("Your order is empty") 
    end 
end 

def customize 
    @renderable_partials = [1, 2, 3] 
    @order = find_order 

    if @order.nil? 
    redirect_to_index("Your order is empty") 
    end 
end 

def save_purchase 
@cart = find_cart 
@order = find_order(params[:cart_owner]) 
@order.add_line_items_from_cart(@cart) 

redirect_to :action => 'customize' 
end 

def save_customize 
@order = find_order 

if @order.save 
    redirect_to :action => 'purchase' 
else 
    flash[:error] = "Your information could not be saved" 
    redirect_to :action => 'customize' 
end 
end 
-SNIP- 

order.rb(模型)

class Order < ActiveRecord::Base 
has_many :line_items 
has_many :line_item_attributes 
accepts_nested_attributes_for :line_items 
accepts_nested_attributes_for :line_item_attributes 

def add_line_items_from_cart(cart) 
    cart.items.each do |item| 
    li = LineItem.from_cart_item(item) 
    line_items << li 
    end 
end 
end 

line_item.rb (型號)

class LineItem < ActiveRecord::Base 
belongs_to :order 
belongs_to :item 
has_many :line_item_attributes 
accepts_nested_attributes_for :line_item_attributes 

def self.from_cart_item(cart_item) 
    li = self.new 
    li.item = cart_item.item 
    li.quantity = cart_item.quantity 
    li.total_price = cart_item.price 

    li.quantity.times do |single_item| 
    lia = LineItemAttribute.new 
    li.line_item_attributes << lia 
    end 

    li 
end 
end 

line_item_attributes.rb(模型)

class LineItemAttribute < ActiveRecord::Base 
belongs_to :order 
belongs_to :line_item 
end 

感謝您的幫助!

+1

這個問題是令人生畏巨大的,可能有多個問題與設計。我認爲你應該回到一個更簡單的問題,它使用相同的概念,而不是試圖一次性解答整個問題。有一個問題需要注意:我認爲LineItemAttributes屬於訂單和line_items可能會造成混淆(但可能很方便)。爲了現在簡化,是不是隻有一個訂單有LineItems,LineItem是否有LineItem屬性?在任何情況下,您都需要簡化您的問題以便在此處進行回答,恕我直言。 – 2010-01-27 18:41:43

+0

你說得對,這個問題都很長,以及你如何簡化它。我會再試一次,讓它更短,更簡單。謝謝。 – John 2010-01-27 21:59:45

回答

1

我建議將Order和LineItems創建移動到單獨的「服務對象」或「表單對象」。在服務/表單對象中,將訂單和行項目創建包裝在單個事務中。代碼將更容易閱讀,並且您的模型不會受到交叉模型的污染。從checkout控制器中,將@cart對象傳遞給服務對象,而不是直接調用Order對象。

看#2和有關服務對象更多信息這篇文章的#3:http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/