4

Does counter_cache increments and decrements fire active_record callbacks ?

User << AR

  has_many :cups

  after_update :do_something

  def do_something
     "Will I be called when number of cups updated ?"
  end

end

Cup << AR

   belongs_to :user, counter_cache: true

end

In the above code will the function do_something be called when a new cup is added and it belongs to a user, update will be called on that user to update the cups_count, but from what I have tried it seems like the counter_cache updates don't fire callbacks, may be because they are themselves inside callbacks ?

Thanks

Abid
  • 7,149
  • 9
  • 44
  • 51

2 Answers2

7

From the source for counter cache, it seems that ActiveRecord is doing a direct database update, which will skip callbacks.

update_all(updates.join(', '), primary_key => id )

According to the documentation for update_all, it does skip callbacks.

davogones
  • 7,321
  • 31
  • 36
1

As @davogones mentions using callbacks is out, but you can still do something similar by overriding the update_counters method in your parent object.

In my case I needed to do something if the counter_cache count exceeded a certain value:

class Cups < ApplicationRecord
  belongs_to :user, :counter_cache => true
end

class User < ApplicationRecord
  has_many :cups

  # This will be called every time there is a counter_cache update, + or - 
  def self.update_counters(id, counters)
    user = User.find(id)
    if user.cups_count + counters['cups_count'] >= some_value
      user.do_something!
    end
    super(id, counters) # continue on with the normal update_counters flow.
  end
end

See update_counters documentation for more info.

Simon L. Brazell
  • 1,132
  • 8
  • 14