One of the most convenient features of Rails is the ability to track attribute changes. Rails 7 is releasing soon and bringing in a lot of new features as a treat for developers. One of the many features that Rails 7 is introducing, is that we can also track the associated object.

This Rails ActiveRecord specific PR has added two methods for tracking the changes for the belongs_to association. In this article, we will discuss these two new methods with the help of examples.

1. association_changed?

The association_changed? method tells if a different associated object has been assigned and the foreign key will be updated in the next save.

Let's take an example of the following Event and Organizer model structure:

class Event
  belongs_to :organizer
end

class Organizer
  has_many :events
end

Before Rails 7, one could only track the change in the target of a belongs_to association by keeping a track of its foreign key. Here's an example:

class Event
  belongs_to :organizer
  before_save :track_change
    
  private
    
  def track_change
    if organizer_id_changed?
      #track something
    end
  end
end

The above example tracks a change in the foreign key (organizer_id), change in the foreign key accordingly means a change in the target of the belongs_to association.

In Rails 7 with the association_changed? method, we can directly check if the associated object is updated or not.

class Event
  belongs_to :organizer
  before_save :track_change
    
  private
    
  def track_change
    if organizer_changed?
      #track something
    end
  end
end

2. association_previously_changed?

The association_previously_changed? method tells if the previous save updated the association to reference a different associated object.

So for the above example, we can also check if the organizer association had previously changed using the organizer_previously_changed? method which will return true if the organizer association was changed in the last save.

> event.organizer
=> #<Organizer id: 1, name: "Organization 1">

> event.organizer = Organizer.second
=> #<Organizer id: 2, name: "Organization 2">

> event.organizer_changed?
=> true

> event.organizer_previously_changed?
=> false

> event.save!
=> true

> event.organizer_changed?
=> false

> event.organizer_previously_changed?
=> true

Similarly, we can track changes on removing the association:

> event.organizer
=> #<Organizer id: 2, name: "Organization 2">

> event.organizer = nil
=> true

> event.organizer_changed?
=> true

> event.save!
=> true

> event.organizer_previously_changed?
=> true

Hope these examples help you to understand the new tracking methods Rails 7 is introducing. We can now track the actual association change instead of tracking the id of the associated object.

Thank you for reading! ❤️

References:


1. Rails 7 release notes

2. PR - Add change tracking methods for belongs_to associations