module Dirty

Ruby on Rails edge

Since v3.0.20

Available in: v3.0.20 v3.1.12 v3.2.22.5 v4.0.13 v4.1.16 v4.2.11.3 v5.0.7.2 v5.1.7 v5.2.8.1 v6.0.6.1 v6.1.7.10 v7.0.10 v7.1.6 v7.2.4 v8.0.5.1 v8.1.4 edge

Active Model Dirty

Provides a way to track changes in your object in the same way as Active Record does.

The requirements for implementing ActiveModel::Dirty are:

  • ‘include ActiveModel::Dirty` in your object.

  • Call define_attribute_methods passing each method you want to track.

  • Call ‘*_will_change!` before each change to the tracked attribute.

  • Call changes_applied after the changes are persisted.

  • Call clear_changes_information when you want to reset the changes information.

  • Call restore_attributes when you want to restore previous data.

A minimal implementation could be:

“‘ class Person

include ActiveModel::Dirty

define_attribute_methods :name

def initialize
  @name = nil
end

def name
  @name
end

def name=(val)
  name_will_change! unless val == @name
  @name = val
end

def save
  # do persistence work

  changes_applied
end

def reload!
  # get the values from the persistence layer

  clear_changes_information
end

def rollback!
  restore_attributes
end

end “‘

A newly instantiated Person object is unchanged:

“‘ person = Person.new person.changed? # => false “`

Change the name:

“‘ person.name = ’Bob’ person.changed? # => true person.name_changed? # => true person.name_changed?(from: nil, to: “Bob”) # => true person.name_was # => nil person.name_change # => [nil, “Bob”] person.name = ‘Bill’ person.name_change # => [nil, “Bill”] “‘

Save the changes:

“‘ person.save person.changed? # => false person.name_changed? # => false “`

Reset the changes:

“‘ person.previous_changes # => {“name” => [nil, “Bill”]} person.name_previously_changed? # => true person.name_previously_changed?(from: nil, to: “Bill”) # => true person.name_previous_change # => [nil, “Bill”] person.name_previously_was # => nil person.reload! person.previous_changes # => {} “`

Rollback the changes:

“‘ person.name = “Uncle Bob” person.rollback! person.name # => “Bill” 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”]} “‘

If an attribute is modified in-place then make use of *_will_change! to mark that the attribute is changing. Otherwise Active Model can’t track changes to in-place attributes. Note that Active Record can detect in-place modifications automatically. You do not need to call ‘*_will_change!` on Active Record models.

“‘ person.name_will_change! person.name_change # => [“Bill”, “Bill”] person.name << ’y’ person.name_change # => [“Bill”, “Billy”] “‘

Methods can be invoked as name_changed? or by passing an argument to the generic method ‘attribute_changed?(“name”)`.

Includes

Extends

Methods (defined here)

Private methods (9)

Show private methods Implementation detail — not part of the public API.

Used by

Included by (2)

Methods (inherited)

From ActiveModel::AttributeMethods (4)
From ActiveSupport::Concern (3)

Type at least 2 characters to search.

Use the arrow keys to navigate results, Enter to open one, Escape to close.

Keyboard shortcuts

/
Focus search
⌘K / Ctrl-K
Command palette
?
This help
Esc
Close