Sometimes in Rails applications we need to perform an action based on a change in a particular attribute of a model.
For example, suppose we have an event management site and we need to notify the event attendees that the privacy of an event has changed. The
ActiveRecord::AttributeMethods::Dirty check comes in handy in such scenarios.
The Event model has an enum attribute of privacy, and privacy can have the following values:
- Private (invite only) (DEFAULT VALUE)
- Public (open for organizational users)
- Open (open for the general public)
In the after_save callback in the Event model, we’ll have following callbacks:
1 2 after_save :notify_attendees_of_privacy_change, if: :saved_change_to_privacy? before_save :destroy_outsiders, if: :will_save_change_to_privacy?
1 2 3 def notify_attendees_of_privacy_change EventMailer.notify_attendees_of_privacy_change(self).deliver_later end
1 2 3 def destroy_outsiders outsiders.destroy_all if outsiders.exists? end
ActiveModel::Dirty provides us with some other helper methods too, such as:
1 2 3 4 5 6 7 8 9 10 11 event = Event.create(title: 'Birthday Party', privacy: 0) event.title = 'Farewell' # Before saving the Event object, the following are the dirty checks: event.changed? # => true event.title_changed? # => true event.title_changed?(from: 'Birthday Party', to: 'Farewell') # => true event.title_was # => 'Birthday Party' event.title_change # => ['Birthday Party', 'Farewell']