質問

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:

  1. Load or create o. o.a_changed? will be false.
  2. o.a = pancakes, o.a_changed? will be true.
  3. 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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top