2011-03-16 3 views
2

많은 'line_items'가있는 '주문'이라는 두 개의 관련 테이블 세트가 있습니다. 광고 항목과 연결된 수량도 있습니다 (예 :: total_cache에 대한 카운터 캐시

Order1가
LINE_ITEM A : 3
LINE_ITEM의 B : 수량 '초보자 직조 바구니' '는 거짓이 흡혈 안내'수량 : I 마이그레이션을 설정하면 1

내가 양을 포함 할 수있다 사용 : I 라인 항목의 수량에 통과 할 수없는이기 때문에 나에게 항목 (4)의 정확한 수를 제공

Order.find(:all).each do |o| 
    o.update_attribute :line_items_count, o.line_items.map(&:quantity).sum 
end 

을,하지만 난 나타나지 않는 것은 주문 모델에 그것을 할 수 있도록 , 광고 항목 수를 계산합니다 (2).

그래서 LINE_ITEM 모델에서 내가 가진 :

belongs_to :order, :counter_cache => true 

올바르게 4 대신이 말한다 있도록 내가 양을 지정할 수있는 방법이 있나요?

답변

3

종속 항목의 수 (합계가 아닌)를 유지하기위한 'counter_cache'기능.

루비 코드를 몇 줄 써서 쉽게 얻을 수 있습니다.

orders 테이블에 line_items_sum이라는 열이 있다고 가정합니다. 0

class AddLineItemsSumToOrder < ActiveRecord::Migration 
    def self.up 
    add_column :orders, :line_items_sum, :integer, :default => 0 
    end 

    def self.down 
    remove_column :orders, :line_items_sum 
    end 
end 


class Order < ActiveRecord::Base 
    has_many :line_items 
end 

는 이제 LineItem 클래스에 콜백을 추가하려면이 열의 값은 기본합니다.

class LineItem < ActiveRecord::Base 
    validates_numericality_of :quantity 
    belongs_to :order 
    after_save :update_line_items_sum 

private 
    def update_line_items_sum 
    return true unless quantity_changed? 
    Order.update_counters order.id, 
     :line_items_sum => (quantity - (quantity_was || 0)) 
    return true 
    end 
end 
+0

안녕하세요, 코드 예제에 감사드립니다. 매우 유용합니다. 사실은 이것을 구현했지만 before_save 콜백에 대한 업데이트는 after_save 대신 콜백했다. 이것이 어떤 차이를 만들겠습니까? – GrahamJRoy

+0

'before_save' 파일에'LineItem'이 저장되어 있지 않다면 잘못된 정보로 업데이트 할 수 있습니다. – theIV

+0

'before_save' 콜백을 실행 한 후 save가 실패 할 수 있습니다. 그럴 경우'Order' 테이블을 조기에 업데이트하고 있습니다. –

1

최선의 방법은 전체 수량을 캐싱하기위한 고유 한 방법을 작성하는 것입니다. 카운터를 보관하기 위해 "Rails 방식"을 따르지 않는다면, 직접 작성하는 것이 좋습니다.