Track unsaved attribute changes.
A newly instantiated object is unchanged:
Change the name:
person.name = 'Bob' person.changed? # => true person.name_changed? # => true person.name_was # => 'uncle bob' person.name_change # => ['uncle bob', 'Bob'] person.name = 'Bill' person.name_change # => ['uncle bob', 'Bill']
Save the changes:
person.save person.changed? # => false person.name_changed? # => false
Assigning the same value leaves the attribute unchanged:
person.name = 'Bill' person.name_changed? # => false person.name_change # => nil
Which attributes have changed?
Before modifying an attribute in-place:
person.name_will_change! person.name << 'by' person.name_change # => ['uncle bob', 'uncle bobby']
DIRTY_SUFFIXES = ['_changed?', '_change', '_will_change!', '_was']
As it says here at the bottom if you do in-place modifications using << you’ll need to call the will_change method!
This also goes for bang methods. So:
person = Person.first person.name.downcase! person.save
will not save anything! Save will never be called. To get the name saved you need to do
person = Person.first person.name_will_change! person.name.downcase! person.save
This will save the name.
If you call save, and no attributes are “dirty” (changed), then an update query will not happen against the database, and thus updated_at and updated_on will not be set.
You’ll need to modify at least one field to get updated_at and updated_on to set themselves.