So I have a Vendor
model, and a Sale
model. An entry is made in my Sale model whenever an order is placed via a vendor.
On my vendor
model, I have 3 cache columns. sales_today
, sales_this_week
, and sales_lifetime
.
For the first two, I calculated it something like this:
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
So that resets that value everytime it is accessed and re-calculates it based on the most current records.
The weekly one is similar but I use a range of dates instead of today.
But...I am not quite sure how to do Lifetime data.
I don't want to clear out my value and have to sum all the Sale.amount
for all the sales records for my vendor, every single time I update this record. That's why I am even implementing a cache in the first place.
What's the best way to approach this, from a performance perspective?
I might use ActiveRecord's sum
method in this case ( 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")
This would mean you wouldn't have to load lots of sales objects in memory to add the amounts.
You can use callbacks on the create and destroy events for your Sales model:
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.