2013-04-22 4 views
0

그래서 Vendor 모델과 Sale 모델이 있습니다. 주문은 판매 업체를 통해 주문 될 때마다 내 판매 모델에 입력됩니다.누적 된 평생 판매 수치를 추적하는 가장 효율적인 방법은 무엇입니까?

vendor 모델에는 3 개의 캐시 열이 있습니다. sales_today, sales_this_weeksales_lifetime. 처음 두 들어

, 나는 이런 식으로 뭔가를 계산 :

def update_sales_today 
    today = Date.today.beginning_of_day 
    sales_today = Sale.where("created_at >= ?", today).find_all_by_vendor_id(self.id) 
    self.sales_today = 0 
    sales_today.each do |s| 
     self.sales_today = self.sales_today + s.amount 
    end 
    self.save  
    end 

그래서 가장 최근의 기록에 액세스 할 때 다시 계산합니다 기반으로 그 값을 매번 다시 설정하는.

주간지는 비슷하지만 오늘 대신 날짜 범위를 사용합니다.

하지만 ... 평생 데이터를 처리하는 방법을 잘 모르겠습니다.

나는 내 값을 지우고 내 공급 업체의 모든 판매 기록에 대해 Sale.amount을 모두 합산해야합니다.이 레코드를 업데이트 할 때마다. 이것이 내가 처음으로 캐시를 구현하는 이유입니다.

성능 관점에서이 방법에 접근하는 가장 좋은 방법은 무엇입니까?

답변

1

. 하나의 올인원 :

today = Date.today 
vendor_sales = Sale.where(:vendor_id => self.id) 

self.sales_today =  vendor_sales. 
         where("created_at >= ?", today.beginning_of_day). 
         sum("amount") 

self.sales_this_week = vendor_sales. 
         where("created_at >= ?", today.beginning_of_week). 
         sum("amount") 

self.sales_lifetime = vendor_sales.sum("amount") 

이렇게하면 금액을 추가하기 위해 메모리에 많은 판매 개체를로드 할 필요가 없습니다.

+0

음 ... 당신이 'vendor_sales = Sum.where ...'라고 말했을 때'Sale.where ... '를 의미 했습니까? 이'sum' 메소드는 확실히 흥미 롭습니다. Btw, 나는이 접근법을 정말로 좋아한다. 그것은 훨씬 더 건조하게 만듭니다. – marcamillion

+0

이것은 아주 좋습니다! 존재하지 않았다. 캐시 컬럼을 갖는 것만 큼 효율적입니까? – AlexBrand

+0

나는 그것이 "그것이 의존한다"라고 생각한다. 열 (또는 Redis 등의 다른 곳)에서 결과를 캐싱하는 것이 여전히 유익 할 것입니다. 어쨌든 일반적으로 값을 추가하기 위해 루비 객체를로드하는 대신 합계 쿼리를 사용하는 것을 선호합니다. – rossta

0

당신은 당신의 판매 모델의 생성과 파괴 이벤트에 대한 콜백을 사용할 수 있습니다 :이 경우 (docs)에서 액티브의 sum 방법을 사용할 수 있습니다

class SalesController < ApplicationController 

    after_save :increment_vendor_lifetime_sales 
    before_destroy :decrement_vendor_lifetime_sales 

    def increment_vendor_lifetime_sales 
     vendor.update_attribute :sales_lifetime, vendor.sales_lifetime + amount 
    end 

    def decrement_vendor_lifetime_sales 
     vendor.update_attribute :sales_lifetime, vendor.sales_lifetime - amount 
    end 
end