2013-04-22 65 views
0

所以我有一個Vendor模型,和一個Sale模型。每當通過供應商下訂單時,我的銷售模式都會進行輸入。追蹤累計終身銷售額的最有效方法是什麼?

在我vendor模式,我有3個緩存列。 sales_todaysales_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

我可能會使用ActiveRecord的sum方法,在這種情況下(docs)。 All in one:

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'方法看起來很有趣。順便說一句,我非常喜歡這種方法。它使它更乾燥。 – marcamillion 2013-04-22 12:20:39

+0

這太棒了!不知道這存在。這與緩存列一樣高效嗎? – AlexBrand 2013-04-22 16:46:08

+0

我想答案是「這取決於」。將結果緩存到列(或其他地方,如Redis等)可能仍然有好處。無論如何,我通常更喜歡使用sum查詢而不是加載ruby對象來添加值。 – rossta 2013-04-22 16:51:23

0

您可以使用在創建和銷燬事件回調您的銷售模式:

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 
相關問題