Pitfall: ActiveRecord callbacks: Method call with multiple conditions

Updated . Posted . Visible to the public. Repeats.

In the following example the method update_offices_people_count won't be called when office_id changes, because it gets overwritten by the second line:

after_save :update_offices_people_count, :if => :office_id_changed? # is overwritten …
after_save :update_offices_people_count, :if => :trashed_changed? # … by this line

Instead write:

after_save :update_offices_people_count, :if => :office_people_count_needs_update?

private

def office_people_count_needs_update?
  office_id_changed? || trashed_changed?
end

Or, move the conditions into the callback. This also allows you test the conditions more easily using a unit test:

after_save :update_offices_people_count

private

def update_offices_people_count
  if office_id_changed? || trashed_changed?  
    ...
  end
end

Also see the card on testing conditional validations.

Martin Straub
Last edit
Michael Leimstädtner
License
Source code in this card is licensed under the MIT License.
Posted by Martin Straub to makandra dev (2013-04-24 14:09)