Update Post attribute when new Rating is created
-
28-06-2021 - |
Pregunta
I have a Post model which has many ratings and I would like to store the average ratings figure for each post in the post ratings db column. I have a counter cache on the post model which counts the number of ratings.
I have the following code in my post.rb
def update_rating
if self.ratings_count_changed?
self.rating = self.ratings.average(:rating)
end
end
I had this as a before_save callback so whenever the post is edited and saved it updates the ratings, not very useful.
Is there a way I can call this method whenever a new rating is created?
Solución
One way of getting closer to your goal is to add after_create
callback to Rating
model:
class Rating < ActiveRecord::Base
belongs_to :post
# ...
after_create :update_post_average_rating
def update_post_average_rating
self.post.update_attributes(:rating => self.post.ratings.average(:rating))
end
end
Or even more OO friendly version:
class Post < ActiveRecord::Base
has_many :ratings
# ...
def update_average_rating
update_attributes(:rating => self.ratings.average(:rating))
end
end
class Rating < ActiveRecord::Base
belongs_to :post
# ...
after_create :update_post_average_rating
def update_post_average_rating
self.post.update_average_rating
end
end
Otros consejos
Do you think about storing average rating in rating model instead post model? In that case you don't need any callback and you need recalc average by first request after changes.
Instead of before_save on post, do an after_create on the rating because it sounds like you need to update that rating score when a new rating is created, not before the post is saved.
How about putting this into Rating model:
after_create :update_post_average_rating
def update_post_average_rating
self.post.rating = #....
end