I need to update attribute :average_rate when new comment is added. I have in comments.rb
belongs_to :page, :counter_cache => true
and in page.rb
has_many :comments
after_save :update_average_rate
and update_average_rate method in page.rb
def update_average_rate(comment)
if comments_count_changed?
write_attribute :average_rate, (comments.sum(:rate) / comments.count.to_f).ceil
end
end
but it doesnt work. When I am doing
raise comments_count_changed?.inspect
in update_average_rate method, it outputs "false" , but comments_count is changed. What I am doing wrong? Thanks in advance
Your problem is that counter updates don't actually set the "changed" flags to true.
For a column/attribute a
, a_changed?
will be true if and only if a
has been changed but not saved to the database. The basic behavior goes like this:
o
. o.a_changed?
will be false.o.a = pancakes
, o.a_changed?
will be true.o.save
, o.a_changed?
will be false.You're using :counter_cache
but internally, that uses update_counters
and that:
simply does a direct SQL update for the record with the given ID, altering the given hash of counters by the amount given by the corresponding value
So after update_counters
has been called, the counter attribute will not be marked as changed as the counter value in the database will be the new one.
I think you'll have to move your average_rate
logic into an after_save
callback on Comment.