I have three models, User, Venue, Rating, as follows:
class User < ActiveRecord::Base
has_many :ratings
end
class Venue < ActiveRecord::Base
has_many :ratings
end
class Rating < ActiveRecord::Base
belongs_to :user
belongs_to :venue
end
Users are able to rate venues from 0-5. Users may rate the venue as frequently as they want, and often their are different ratings from the same user on the same venue created within minutes of each other.
I want to be able to provide an average rating of a venue from the past hour, however I only wish to consider a single rating per user from the time period. So if a user rates the same venue multiple times in the past hour, only their most recent rating will be accounted for.
Currently I have this:
class Venue < ActiveRecord::Base
has_many :ratings
def past_hour_average
ratings = self.ratings.where(:created_at => 1.hour.ago..Time.now).uniq_by(&:user_id)
# loop through each record and compute average
sum = 0
ratings.each do |rating|
sum += rating.value
end
return sum / ratings.size
end
end
This method seems inefficient however. Every time I want the rating of a venue I have to calculate it. Under the assumption that there will be many users frequently rating a single venue what would a better approach to calculating an average rating be?