module Mongoid::Changeable
Defines behavior for dirty tracking.
@since 4.0.0
Public Instance Methods
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
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
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
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
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
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
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
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 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
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
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
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
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
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
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
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
# 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