2013-04-22 3 views
0

Итак, у меня есть модель Vendor и модель Sale. Запись производится в моей модели продажи, когда заказ отправляется через поставщика.Каков наиболее эффективный способ отслеживать накопленный показатель продаж за всю жизнь?

На моей модели vendor у меня есть 3 столбца кеша. sales_today, sales_this_week, и sales_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

я мог бы использовать sum метод ActiveRecord в этом случае (docs). Все в одном:

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

Hrmm ... когда вы сказали 'vendor_sales = Sum.where ...' вы имели в виду 'Sale.where ...'? Этот метод 'sum' выглядит очень интересно. Кстати, мне очень нравится этот подход. Это делает его намного более сухим. – marcamillion

+0

Это замечательно! Не знал, что это существовало. Это так же эффективно, как наличие столбца кэша? – AlexBrand

+0

Я полагаю, что ответ «это зависит». Вероятно, все еще полезно кэшировать результат по столбцу (или где-то еще, например, в Redis и т. Д.). В любом случае я обычно предпочитаю использовать запрос суммы, а не загружать объекты ruby ​​для добавления значений. – rossta

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 

 Смежные вопросы

  • Нет связанных вопросов^_^