Dirty Associations


I found an area where I don’t totally understand the behavior of the dirty tracking feature in Active Record. It appears as though changes are tracked when I assign a persistent object (already has an id) to the association but not tracked when I assign a new record to the association.

Here’s a test that highlights the difference:


Is the difference between the two usages intentional?


Is the difference between the two usages intentional?

Nope, looks like a side-effect of the implementation to me.

Poking around a little, it's completely an implementation side-effect, and only appears in the exact case you've described. For instance, assigning to a has_many doesn't show up in .changes either:

   def test_changed_includes_new_record_assignments
     album = Album.create! :title => "Give Up the Ghost"
     album.artist = Artist.new :name => "Brandi Carlile"
     assert album.changes.any?

In the belongs_to case in your example, note that the change does get recorded fairly early (before the before_save callback is invoked), so you're OK using the dirty tracking in callbacks / observers.

--Matt Jones