Using Ruby 1.9.2, Rails 3.1. I have the following code:
# review.rb
def calculate_rating(reviewable)
total_rating = Review.select("rating").where(:reviewable_id => self.reviewable_id)
sum_rating = total_rating.sum(:rating)
new_rating_average = sum_rating.to_f / total_rating.size
reviewable.update_attribute(:rating_average, new_rating_average)
end
total_rating is actually used to get the total counts of the number of ratings returned, whereas sum_rating is used to sum each total_rating. I notice that my query is run multiple times to achieve the result.
Is there any way to refactor this to increase the performance?
Thanks.
The active record api exposes the SQL average function so you should be able to do
More generally you may need to write custom sql, for example if the average function didn’t exist, you could write
if you want to count multiple things with differing sets of conditions you can use things like
to get, in 1 query the number of ratings, their sum and and the number of ratings > 5.
Use this with caution though, you don’t want to replace 2 fast queries with one very slow query!.