2010-01-27 10 views
0

레일즈 애자일 웹 개발 (버전 3)을 기반으로 장바구니를 만들고 있습니다. 나는 "items"가 "cart"에 추가 된 곳을 설정하고 체크 아웃 과정을 시작할 때 "line_items"와 같은 "order"객체에 추가합니다. "line_items"는 수량에 관계없이 하나의 "항목"을 나타냅니다. 지금까지이 책의 예에서 벗어나지 않았습니다. 그러나, 여기가 나를 위해 복잡 해지는 곳입니다. 내 스토어의 모든 "항목"은 텍스트로 사용자 정의 할 수 있으며 "주문"에 "line_items"가 포함 된 맞춤 텍스트를 저장할 수 있어야합니다.여러 모델로 된 레일 체크 아웃 양식

위에서 언급했듯이 "line_items"는 "항목"의 수량을 보유하지만 고객은 모든 항목을 사용자 정의 할 수 있어야하므로 각 "line_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"에 묶여 있어야하기 때문입니다. 나는 레일스가 "@ 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

이 질문은 dauntingly 거대한, 그리고 디자인으로 여러 문제가있을 수 있습니다.나는이 전체 질문을 한 번에 대답하려고하지 않고 동일한 개념을 사용하는 간단한 질문으로 돌아 가야한다고 생각합니다. 한 가지 질문 : LineItemAttributes를 orders 및 line_item에 속하게하는 것이 혼란 스럽지만 편리 할 수 ​​있습니다. 지금 단순화하기 위해서, Order가 LineItem을 가지고 있고 LineItem이 LineItem 속성을 가지고 있지 않은가? 어쨌든 여기서 답을 얻으려면 질문을 단순화해야합니다. IMHO. –

+0

당신이 맞습니다, 그 질문은 오래 갈 것입니다. 다시 시도하고 더 짧고 단순하게 만들 것입니다. 감사. – John

답변

1

Order 및 LineItems 생성을 별도의 "서비스 개체"또는 "양식 개체"로 옮기는 것이 좋습니다. 서비스/양식 객체에서 주문 및 품목 생성을 단일 트랜잭션으로 래핑합니다. 코드는 읽기 쉽고 모델은 교차 모델로 오염되지 않습니다. 체크 아웃 컨트롤러에서 Order 개체를 직접 호출하는 대신 @cart 개체를 서비스 개체로 전달하십시오. # 2 및 서비스 개체에 대한 자세한 정보를 원하시면,이 게시물의 # 3에서

봐 : http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/