ActiveRecord::Dirty
Track unsaved attribute changes.
A newly instantiated object is unchanged:
person = Person.find_by_name('uncle bob') person.changed? # => false
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?
person.name = 'bob' person.changed # => ['name'] person.changes # => { 'name' => ['Bill', 'bob'] }
Before modifying an attribute in-place:
person.name_will_change! person.name << 'by' person.name_change # => ['uncle bob', 'uncle bobby']
Files
- activerecord/lib/active_record/dirty.rb
3Notes
Bang methods also need will_change!
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.
update_on and update_at only set on attribute change
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.
You can turn off dirty objects
If you expierence problems with dirty objects you can turn it off:
ActiveRecord::Base.partial_updates = false