2011-12-19 19 views
0

使用Ruby 1.9.2,Rails 3.1。我有以下代碼:在Rails中重構此方法以防止SQL查詢運行兩次

# 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實際使用獲得的評分數量的總計數退回,而sum_rating用來總結各total_rating。我注意到我的查詢被多次運行以實現結果。

有什麼辦法可以重構這個來提高性能嗎?

謝謝。

回答

1

活動記錄API公開SQL平均功能,所以你應該能夠做到

average_rating = Review.where(:reviewable_id => self.reviewable_id).average(:rating) 

更普遍,您可能需要自定義的SQL編寫,例如,如果平均計算功能並不存在,你可以寫

select count(*) as c, sum(rating) as total from ratings where (...) 

如果你想與不同組的條件下,你可以使用之類的東西

select count(*) as number_of_ratings, SUM(IF(rating > 5, 1, 0)) as number_of_ratings_greater_than_5, SUM(rating) as total_score 
來算多的東西

要獲得,在1查詢評級數量,他們的總和和評級數量> 5. 雖然,你不想用一個非常慢的查詢替換2快速查詢!

+0

OMG,我不能更多感謝第一個SQL語句! – Victor 2011-12-19 17:32:09