| Module | ActiveRecord::Dirty |
| In: |
vendor/rails/activerecord/lib/active_record/dirty.rb
|
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']
# File vendor/rails/activerecord/lib/active_record/dirty.rb, line 37
37: def self.included(base)
38: base.attribute_method_suffix '_changed?', '_change', '_will_change!', '_was'
39: base.alias_method_chain :write_attribute, :dirty
40: base.alias_method_chain :save, :dirty
41: base.alias_method_chain :save!, :dirty
42: base.alias_method_chain :update, :dirty
43: base.alias_method_chain :reload, :dirty
44:
45: base.superclass_delegating_accessor :partial_updates
46: base.partial_updates = true
47: end
Do any attributes have unsaved changes?
person.changed? # => false person.name = 'bob' person.changed? # => true
# File vendor/rails/activerecord/lib/active_record/dirty.rb, line 53
53: def changed?
54: !changed_attributes.empty?
55: end
Map of changed attrs => [original value, new value]
person.changes # => {}
person.name = 'bob'
person.changes # => { 'name' => ['bill', 'bob'] }
# File vendor/rails/activerecord/lib/active_record/dirty.rb, line 69
69: def changes
70: changed.inject({}) { |h, attr| h[attr] = attribute_change(attr); h }
71: end