Module: ActiveRecord::Dirty

Defined in:
lib/active_record/dirty.rb

Overview

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']

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

DIRTY_SUFFIXES =
['_changed?', '_change', '_will_change!', '_was']

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/active_record/dirty.rb', line 39

def self.included(base)
  base.attribute_method_suffix *DIRTY_SUFFIXES
  base.alias_method_chain :write_attribute, :dirty
  base.alias_method_chain :save,            :dirty
  base.alias_method_chain :save!,           :dirty
  base.alias_method_chain :update,          :dirty
  base.alias_method_chain :reload,          :dirty

  base.class_attribute :partial_updates
  base.partial_updates = true

  base.send(:extend, ClassMethods)
end

Instance Method Details

#changedObject

List of attributes with unsaved changes.

person.changed # => []
person.name = 'bob'
person.changed # => ['name']


65
66
67
# File 'lib/active_record/dirty.rb', line 65

def changed
  changed_attributes.keys
end

#changed?Boolean

Do any attributes have unsaved changes?

person.changed? # => false
person.name = 'bob'
person.changed? # => true

Returns:

  • (Boolean)


57
58
59
# File 'lib/active_record/dirty.rb', line 57

def changed?
  !changed_attributes.empty?
end

#changesObject

Map of changed attrs => [original value, new value].

person.changes # => {}
person.name = 'bob'
person.changes # => { 'name' => ['bill', 'bob'] }


73
74
75
# File 'lib/active_record/dirty.rb', line 73

def changes
  changed.inject({}) { |h, attr| h[attr] = attribute_change(attr); h }
end

#reload_with_dirty(*args) ⇒ Object

reload the record and clears changed attributes.



93
94
95
96
97
# File 'lib/active_record/dirty.rb', line 93

def reload_with_dirty(*args) #:nodoc:
  record = reload_without_dirty(*args)
  changed_attributes.clear
  record
end

#save_with_dirty(*args) ⇒ Object

Attempts to save the record and clears changed attributes if successful.



78
79
80
81
82
83
# File 'lib/active_record/dirty.rb', line 78

def save_with_dirty(*args) #:nodoc:
  if status = save_without_dirty(*args)
    changed_attributes.clear
  end
  status
end

#save_with_dirty!(*args) ⇒ Object

Attempts to save! the record and clears changed attributes if successful.



86
87
88
89
90
# File 'lib/active_record/dirty.rb', line 86

def save_with_dirty!(*args) #:nodoc:
  status = save_without_dirty!(*args)
  changed_attributes.clear
  status
end