2011-08-08 2 views
9

모델에 has_many 연관이있는 'orders'및 'items'테이블이 있습니다.연관에서 일부 필드의 트랙 합계 - "sum_cache"

class Order < ActiveRecord::Base 
has_many :items 

class Item < ActiveRecord::Base 
belongs_to :order 

항목은 '수량'필드로 구성되며, 주문은 'quantity_sum'필드로 구성되어 관련 항목의 합계를 추적합니다. 예를 들어

: 나는 주문의 새로운 항목이 추가 될 때마다/수정/삭제 필드 'quantity_sum'가 자동으로 업데이트됩니다 있도록 방법을 찾고있다

Order 1 : name='Toms shopping cart', quantity_sum=12 
Item 1 : name='T-shirt', quantity=10 
Itme 2 : name='Shoes', quantity=2 

. 현재 Item의 after_save 메소드를 사용하여 Order의 'quantity_sum'필드를 업데이트하고 있습니다.

'after_save'외에도 이렇게하는 방법이 있습니까?

연관 개수를 추적하는 "counter_cache"와 비슷하게, 레일스는 연관의 일부 필드의 합계를 자동으로 추적 할 수 있습니까?

감사

+1

콜백 메서드가 올바른지 : 진정한 http://stackoverflow.com/a/5334639/8843 – tal

답변

3

는 테이블에서 quantity_sum 필드를 제거하고 트릭을 할해야 quantity_values ​​

class Order < ActiveRecord::Base 
    has_many :items 

    def quantity_sum 
    self.items.sum(:quantity) 
    end 
end 

을 요약 주문 클래스에 quantity_sum 방법을 추가 할 수 있습니다. 그런 다음 quantity_sum 필드를 업데이트 할 수있는 코드를 제거하면됩니다. 메소드의 이름이 필드 이름과 동일하기 때문에 (삭제하는 것을 잊지 말아야 함),이를 사용하는 코드를 리팩터링 할 필요가 없습니다.

물론이 항목은 시스템의 모든 주문 목록 에서처럼 불필요하게 사용하지 않도록 조심해야합니다. 데이터베이스의 내용이 매우 무거울 수 있습니다. 몇 백 건의 기록을 남겨 두었지만 수천 건의 주문에 비해 성능 문제가 있음을 알 수 있습니다.

은 주문 테이블

+2

을하지만, 방법은 quantity_sum 새로운 쿼리 할 때마다를 발사
그것은 이런 일에 당신을 허용해야 호출됩니다. 동일한 순서로 많은 수의 항목이있는 경우 많은 수의 쿼리가 실행되어 서버 응답 시간이 늘어납니다. 이것을 피하기 위해서 나는 데이터베이스 자체에 합계를 저장하는 것을 고려했다. – jayandra

0

내가 this gem이 your'e이 찾고 무엇이라고 생각에서 해당 quantity_sum 필드를 제거하는 것을 잊지 마십시오.
문서에서 "계산 대신 계산"을 찾으십시오.

class Item < ActiveRecord::Base 
    belongs_to :order 
    counter_culture :order, :column_name => 'quantity_sum', :delta_column => 'quantity' 
end 

class Order < ActiveRecord::Base 
    has_many :items 
end