module Mongoid::Changeable
Defines behaviour 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 17 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 29 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 53 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 65 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 41 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 83 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 97 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 110 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 123 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 138 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 167 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 182 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 198 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 212 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 227 def attribute_will_change!(attr) unless changed_attributes.key?(attr) changed_attributes[attr] = read_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 243 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 248 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