Performing an action via a callback is fairly easy and doable. Sometimes requirement may be a bit enhance that we need to track every change now and then.
On the same note, if we have associations and we wanted to make some changes that needs to be reflected on previous and new values, this dirty concepts can save our time.

This module gives a way to track changes done in an active-record object.

By default, rails include ActiveRecord::Dirty this module.

This gives many powerful methods that helps us to track attribute changes. This methods are based on the attribute recorded in a model.

Lets consider an example to dive in:

We have User class which attributes like name, address and mobile_number.

user = User.find_by_name('Jake')
user.name = 'Sake'   #user's name is reassigned to Sake from Jake
user.changed?        # true
user.changes         #{ "name"=>["Jake", "Sake"] };
# This hash highlights the attribute changed. This can involve multiple attributes as well.
user.name_was        # "Jake";  Returns initial value
user.title_change    # ["Jake", "Sake"]; Returns array of changed values.
# Note: we have called '_change' on title, so it will return only title changes.

Above methods can help to track changes in active-record transaction.

If we want to track changes post-commit(i.e after_commit), we can make use of instance variable called @previously_changed which is a hash. This will return state of active-record attributes as we have obtained in above example via '.changes'.

Note: Using '.changes' in post-commit actions cant be that useful as active-record object loses its values. So, @previously_changed variable can help us.

Lesson:

In one of our assignments, we had a requirement to update count of objects w.r.t to user. In this case, the object can be delegated to any user so the the count would differ for that user. We need to reflect this change to both the user .i.e before change and after_change. Here, ActiveRecord::Dirty helped us to track the user in that transaction to update count of count.

References:

  1. (Rails-ActiveRecord-Dirty-doc)
  2. (ActiveRecord::Dirty-doc)