In ActiveRecord, how to specify a class attribute that is calculated just once for the duration of the page?
Let's say I have an ActiveRecord called Apples, and I want a class method that calculates the total price of every apple in my database, as so:
def Apples.total_price
Apples.sum(:price)
end
This is a method I use in one of my views to make a pie chart. So, something like: Apples.brand("red delicious").sum(:price)/Apples.total_price = % of pie chart
Apples.brand("fuji").sum(:price)/Apples.total_price = another % of pie chart
Apples.total_price is called repeatedly but the value isn't going to change at this point. A) Does Rails make the query repeatedly, or does it know to cache th开发者_Go百科e value? And if it does call it repeatedly, what's the best way to define a method in Apple so that this total_price is just calculated once for the runtime of this view?
The way you've defined it, I believe it is done repeatedly. The logs will show for sure.
Through a technique known as memoization you process the it only if needed. Rails supplies easy memoization for instance methods, but you're on your own for class methods.
Here's how you roll your own memoization for a class method.
class Apple < ActiveRecord::Base
cattr_reader :total_price
def Apple.total_price
@@total_price ||= Apples.sum(:price)
end
end
first way
def total_price
@total_price ||= calc_total_price
end
There is also memoize method. so you can do it this way also
def total_price
#you long running code goes here
end
memoize :total_price
Here you can find some details on it:
http://ryandaigle.com/articles/2008/7/16/what-s-new-in-edge-rails-memoization
精彩评论