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
Moreover, 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']
For more details, here are the official docs on ActiveModel::Dirty, ActiveRecord::AttributeMethods::Dirty - happy checking!