module Mongoid::Changeable

Defines behavior for dirty tracking.

@since 4.0.0

Public Instance Methods

changed() click to toggle source

Get the changed attributes for the document.

@example Get the changed attributes.

model.changed

@return [ Array<String> ] The changed attributes.

@since 2.4.0

# File lib/mongoid/changeable.rb, line 20
def changed
  changed_attributes.keys.select { |attr| attribute_change(attr) }
end
changed?() click to toggle source

Has the document changed?

@example Has the document changed?

model.changed?

@return [ true, false ] If the document is changed.

@since 2.4.0

# File lib/mongoid/changeable.rb, line 32
def changed?
  changes.values.any? { |val| val } || children_changed?
end
changed_attributes() click to toggle source

Get the attribute changes.

@example Get the attribute changes.

model.changed_attributes

@return [ Hash<String, Object> ] The attribute changes.

@since 2.4.0

# File lib/mongoid/changeable.rb, line 56
def changed_attributes
  @changed_attributes ||= {}
end
changes() click to toggle source

Get all the changes for the document.

@example Get all the changes.

model.changes

@return [ Hash<String, Array<Object, Object> ] The changes.

@since 2.4.0

# File lib/mongoid/changeable.rb, line 68
def changes
  _changes = {}
  changed.each do |attr|
    change = attribute_change(attr)
    _changes[attr] = change if change
  end
  _changes.with_indifferent_access
end
children_changed?() click to toggle source

Have any children (embedded documents) of this document changed?

@example Have any children changed?

model.children_changed?

@return [ true, false ] If any children have changed.

@since 2.4.1

# File lib/mongoid/changeable.rb, line 44
def children_changed?
  _children.any?(&:changed?)
end
move_changes() click to toggle source

Call this method after save, so the changes can be properly switched.

This will unset the memoized children array, set new record to false, set the document as validated, and move the dirty changes.

@example Move the changes to previous.

person.move_changes

@since 2.1.0

# File lib/mongoid/changeable.rb, line 86
def move_changes
  @previous_changes = changes
  Atomic::UPDATES.each do |update|
    send(update).clear
  end
  changed_attributes.clear
end
post_persist() click to toggle source

Things that need to execute after a document has been persisted.

@example Handle post persistence.

document.post_persist

@since 3.0.0

# File lib/mongoid/changeable.rb, line 100
def post_persist
  reset_persisted_children
  move_changes
end
previous_changes() click to toggle source

Get the previous changes on the document.

@example Get the previous changes.

model.previous_changes

@return [ Hash<String, Array<Object, Object> ] The previous changes.

@since 2.4.0

# File lib/mongoid/changeable.rb, line 113
def previous_changes
  @previous_changes ||= {}
end
remove_change(name) click to toggle source

Remove a change from the dirty attributes hash. Used by the single field atomic updators.

@example Remove a flagged change.

model.remove_change(:field)

@param [ Symbol, String ] name The name of the field.

@since 2.1.0

# File lib/mongoid/changeable.rb, line 126
def remove_change(name)
  changed_attributes.delete(name.to_s)
end
setters() click to toggle source

Gets all the new values for each of the changed fields, to be passed to a MongoDB $set modifier.

@example Get the setters for the atomic updates.

person = Person.new(:title => "Sir")
person.title = "Madam"
person.setters # returns { "title" => "Madam" }

@return [ Hash ] A Hash of atomic setters.

@since 2.0.0

# File lib/mongoid/changeable.rb, line 141
def setters
  mods = {}
  changes.each_pair do |name, changes|
    if changes
      old, new = changes
      field = fields[name]
      key = atomic_attribute_name(name)
      if field && field.resizable?
        field.add_atomic_changes(self, name, key, mods, new, old)
      else
        mods[key] = new unless atomic_unsets.include?(key)
      end
    end
  end
  mods
end

Private Instance Methods

attribute_change(attr) click to toggle source

Get the old and new value for the provided attribute.

@example Get the attribute change.

model.attribute_change("name")

@param [ String ] attr The name of the attribute.

@return [ Array<Object> ] The old and new values.

@since 2.1.0

# File lib/mongoid/changeable.rb, line 170
def attribute_change(attr)
  attr = database_field_name(attr)
  [changed_attributes[attr], attributes[attr]] if attribute_changed?(attr)
end
attribute_changed?(attr) click to toggle source

Determine if a specific attribute has changed.

@example Has the attribute changed?

model.attribute_changed?("name")

@param [ String ] attr The name of the attribute.

@return [ true, false ] Whether the attribute has changed.

@since 2.1.6

# File lib/mongoid/changeable.rb, line 185
def attribute_changed?(attr)
  attr = database_field_name(attr)
  return false unless changed_attributes.key?(attr)
  changed_attributes[attr] != attributes[attr]
end
attribute_changed_from_default?(attr) click to toggle source

Get whether or not the field has a different value from the default.

@example Is the field different from the default?

model.attribute_changed_from_default?

@param [ String ] attr The name of the attribute.

@return [ true, false ] If the attribute differs.

@since 3.0.0

# File lib/mongoid/changeable.rb, line 201
def attribute_changed_from_default?(attr)
  field = fields[attr]
  return false unless field
  attributes[attr] != field.eval_default(self)
end
attribute_was(attr) click to toggle source

Get the previous value for the attribute.

@example Get the previous value.

model.attribute_was("name")

@param [ String ] attr The attribute name.

@since 2.4.0

# File lib/mongoid/changeable.rb, line 215
def attribute_was(attr)
  attr = database_field_name(attr)
  attribute_changed?(attr) ? changed_attributes[attr] : attributes[attr]
end
attribute_will_change!(attr) click to toggle source

Flag an attribute as going to change.

@example Flag the attribute.

model.attribute_will_change!("name")

@param [ String ] attr The name of the attribute.

@return [ Object ] The old value.

@since 2.3.0

# File lib/mongoid/changeable.rb, line 230
def attribute_will_change!(attr)
  unless changed_attributes.key?(attr)
    changed_attributes[attr] = read_raw_attribute(attr).__deep_copy__
  end
end
reset_attribute!(attr) click to toggle source

Set the attribute back to its old value.

@example Reset the attribute.

model.reset_attribute!("name")

@param [ String ] attr The name of the attribute.

@return [ Object ] The old value.

@since 2.4.0

# File lib/mongoid/changeable.rb, line 246
def reset_attribute!(attr)
  attr = database_field_name(attr)
  attributes[attr] = changed_attributes.delete(attr) if attribute_changed?(attr)
end
reset_attribute_to_default!(attr) click to toggle source
# File lib/mongoid/changeable.rb, line 251
def reset_attribute_to_default!(attr)
  attr = database_field_name(attr)
  if field = fields[attr]
    __send__("#{attr}=", field.eval_default(self))
  else
    __send__("#{attr}=", nil)
  end
end