Module: Mongoid::Changeable
Relationships & Source Files | |
Namespace Children | |
Modules:
| |
Classes:
| |
Extension / Inclusion / Inheritance Descendants | |
Included In:
| |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
ActiveSupport::Concern
|
|
Defined in: | lib/mongoid/changeable.rb |
Overview
Defines behavior for dirty tracking.
Constant Summary
-
ATTRIBUTE_UNCHANGED =
a singleton object to represent an optional
to
orfrom
value that was not explicitly provided to #attribute_changed?Anything.new
Instance Attribute Summary
-
#changed ⇒ Array<String>
readonly
Get the changed attributes for the document.
-
#changed? ⇒ true | false
readonly
Has the document changed?
-
#children_changed? ⇒ true | false
readonly
Have any children (embedded documents) of this document changed?
Instance Method Summary
-
#attribute_before_last_save(attr) ⇒ Object
Returns the original value of an attribute before the last save.
-
#attribute_changed?(attr, from: ATTRIBUTE_UNCHANGED, to: ATTRIBUTE_UNCHANGED) ⇒ true | false
Determine if a specific attribute has changed.
-
#attribute_changed_from_default?(attr) ⇒ true | false
Get whether or not the field has a different value from the default.
-
#attribute_previously_was(attr) ⇒ Object | nil
Get the previous attribute value that was changed before the document was saved.
-
#attribute_was(attr)
Get the previous value for the attribute.
-
#attribute_will_change!(attr) ⇒ Object
Flag an attribute as going to change.
-
#changed_attributes ⇒ Hash<String, Object>
Get the attribute changes.
-
#changes ⇒ Hash<String, Array<Object, Object> ] The changes.
Get all the changes for the document.
-
#children_may_have_changed!
Internal use only
Internal use only
Indicates that the children of this document may have changed, and ought to be checked when the document is validated.
-
#move_changes
Call this method after save, so the changes can be properly switched.
-
#post_persist
Things that need to execute after a document has been persisted.
-
#previous_changes ⇒ Hash<String, Array<Object, Object> ] The previous changes.
Get the previous changes on the document.
-
#remove_change(name)
Remove a change from the dirty attributes hash.
-
#reset_attribute!(attr) ⇒ Object
::Set
the attribute back to its old value. - #reset_attribute_to_default!(attr)
- #reset_attributes_before_type_cast
-
#saved_change_to_attribute(attr) ⇒ Array<Object> | nil
Returns the change to an attribute during the last save.
-
#saved_change_to_attribute?(attr, from: Utils::PLACEHOLDER, to: Utils::PLACEHOLDER) ⇒ true | false
Returns whether this attribute changed during the last save.
-
#setters ⇒ Hash
Gets all the new values for each of the changed fields, to be passed to a MongoDB $set modifier.
-
#will_save_change_to_attribute?(attr, **kwargs) ⇒ true | false
Returns whether this attribute change the next time we save.
-
#attribute_change(attr) ⇒ Array<Object>
private
Get the old and new value for the provided attribute.
- #attributes_before_last_save private
- #changes_before_last_save private
-
#previous_attributes ⇒ Hash
private
Get attributes of the document before the document was saved.
Instance Attribute Details
#changed ⇒ Array<String> (readonly)
Get the changed attributes for the document.
# File 'lib/mongoid/changeable.rb', line 14
def changed changed_attributes.keys.select { |attr| attribute_change(attr) } end
#changed? ⇒ true
| false
(readonly)
Has the document changed?
# File 'lib/mongoid/changeable.rb', line 32
def changed? changes.values.any? { |val| val } || children_changed? end
#children_changed? ⇒ true
| false
(readonly)
This intentionally only considers children and not descendants.
Have any children (embedded documents) of this document changed?
# File 'lib/mongoid/changeable.rb', line 41
def children_changed? @children_may_have_changed || _children.any?(&:changed?) end
Instance Method Details
#attribute_before_last_save(attr) ⇒ Object
Returns the original value of an attribute before the last save.
This method is useful in after callbacks to get the original value of
an attribute before the save that triggered the callbacks to run.
# File 'lib/mongoid/changeable.rb', line 150
def attribute_before_last_save(attr) attr = database_field_name(attr) attributes_before_last_save[attr] end
#attribute_change(attr) ⇒ Array<Object
> (private)
Get the old and new value for the provided attribute.
# File 'lib/mongoid/changeable.rb', line 228
def attribute_change(attr) attr = database_field_name(attr) [ changed_attributes[attr], attributes[attr] ] if attribute_changed?(attr) end
#attribute_changed?(attr, from: ATTRIBUTE_UNCHANGED, to: ATTRIBUTE_UNCHANGED) ⇒ true
| false
Determine if a specific attribute has changed.
# File 'lib/mongoid/changeable.rb', line 266
def attribute_changed?(attr, from: ATTRIBUTE_UNCHANGED, to: ATTRIBUTE_UNCHANGED) attr = database_field_name(attr) return false unless changed_attributes.key?(attr) return false if changed_attributes[attr] == attributes[attr] return false if from != changed_attributes[attr] return false if to != attributes[attr] true end
#attribute_changed_from_default?(attr) ⇒ true
| false
Get whether or not the field has a different value from the default.
# File 'lib/mongoid/changeable.rb', line 284
def attribute_changed_from_default?(attr) return false unless (field = fields[attr]) attributes[attr] != field.eval_default(self) end
#attribute_previously_was(attr) ⇒ Object
| nil
Get the previous attribute value that was changed before the document was saved.
It the document has not been saved yet, or was just loaded from database, this method returns nil for all attributes.
# File 'lib/mongoid/changeable.rb', line 311
def attribute_previously_was(attr) attr = database_field_name(attr) if previous_changes.key?(attr) previous_changes[attr].first else previous_attributes[attr] end end
#attribute_was(attr)
Get the previous value for the attribute.
# File 'lib/mongoid/changeable.rb', line 296
def attribute_was(attr) attr = database_field_name(attr) attribute_changed?(attr) ? changed_attributes[attr] : attributes[attr] end
#attribute_will_change!(attr) ⇒ Object
Flag an attribute as going to change.
# File 'lib/mongoid/changeable.rb', line 328
def attribute_will_change!(attr) return if changed_attributes.key?(attr) changed_attributes[attr] = read_raw_attribute(attr).__deep_copy__ end
#attributes_before_last_save (private)
[ GitHub ]# File 'lib/mongoid/changeable.rb', line 216
def attributes_before_last_save @attributes_before_last_save ||= {} end
#changed_attributes ⇒ Hash<String, Object
>
Get the attribute changes.
# File 'lib/mongoid/changeable.rb', line 51
def changed_attributes @changed_attributes ||= {} end
#changes ⇒ Hash<String, Array<Object
, Object
> ] The
changes.
Get all the changes for the document.
# File 'lib/mongoid/changeable.rb', line 61
def changes changed.each_with_object({}) do |attr, changes| change = attribute_change(attr) changes[attr] = change if change end.with_indifferent_access end
#changes_before_last_save (private)
[ GitHub ]# File 'lib/mongoid/changeable.rb', line 212
def changes_before_last_save @changes_before_last_save ||= {} end
#children_may_have_changed!
Indicates that the children of this document may have changed, and ought to be checked when the document is validated.
# File 'lib/mongoid/changeable.rb', line 22
def children_may_have_changed! @children_may_have_changed = true end
#move_changes
Call this method after save, so the changes can be properly switched.
This will unset the memoized children array, set new record flag to false, set the document as validated, and move the dirty changes.
# File 'lib/mongoid/changeable.rb', line 75
def move_changes @changes_before_last_save = @previous_changes @previous_changes = changes @attributes_before_last_save = @previous_attributes @previous_attributes = attributes.dup @children_may_have_changed = false reset_atomic_updates! changed_attributes.clear end
#post_persist
Things that need to execute after a document has been persisted.
# File 'lib/mongoid/changeable.rb', line 89
def post_persist reset_persisted_descendants reset_attributes_before_type_cast move_changes end
#previous_attributes ⇒ Hash (private)
Get attributes of the document before the document was saved.
# File 'lib/mongoid/changeable.rb', line 208
def previous_attributes @previous_attributes ||= {} end
#previous_changes ⇒ Hash<String, Array<Object
, Object
> ] The
previous
changes.
Get the previous changes on the document.
# File 'lib/mongoid/changeable.rb', line 101
def previous_changes @previous_changes ||= {} end
#remove_change(name)
Remove a change from the dirty attributes hash. Used by the single field atomic updaters.
# File 'lib/mongoid/changeable.rb', line 112
def remove_change(name) changed_attributes.delete(name.to_s) end
#reset_attribute!(attr) ⇒ Object
::Set
the attribute back to its old value.
# File 'lib/mongoid/changeable.rb', line 342
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)
[ GitHub ]# File 'lib/mongoid/changeable.rb', line 347
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
#reset_attributes_before_type_cast
[ GitHub ]# File 'lib/mongoid/changeable.rb', line 356
def reset_attributes_before_type_cast @attributes_before_type_cast = @attributes.dup end
#saved_change_to_attribute(attr) ⇒ Array<Object
> | nil
Returns the change to an attribute during the last save.
# File 'lib/mongoid/changeable.rb', line 161
def saved_change_to_attribute(attr) attr = database_field_name(attr) previous_changes[attr] end
#saved_change_to_attribute?(attr, from: Utils::PLACEHOLDER, to: Utils::PLACEHOLDER) ⇒ true
| false
Returns whether this attribute changed during the last save.
This method is useful in after callbacks, to see the change
in an attribute during the save that triggered the callbacks to run.
# File 'lib/mongoid/changeable.rb', line 176
def saved_change_to_attribute?(attr, from: Utils::PLACEHOLDER, to: Utils::PLACEHOLDER) changes = saved_change_to_attribute(attr) return false unless changes.is_a?(Array) return true if Utils.placeholder?(from) && Utils.placeholder?(to) return changes.first == from if Utils.placeholder?(to) return changes.last == to if Utils.placeholder?(from) changes.first == from && changes.last == to end
#setters ⇒ Hash
Gets all the new values for each of the changed fields, to be passed to a MongoDB $set modifier.
# File 'lib/mongoid/changeable.rb', line 125
def setters mods = {} changes.each_pair do |name, changes| next unless changes old, new = changes field = fields[name] key = atomic_attribute_name(name) if field&.resizable? field.add_atomic_changes(self, name, key, mods, new, old) else mods[key] = new unless atomic_unsets.include?(key) end end mods end
#will_save_change_to_attribute?(attr, **kwargs) ⇒ true
| false
Returns whether this attribute change the next time we save.
This method is useful in validations and before callbacks to determine
if the next call to save will change a particular attribute.
# File 'lib/mongoid/changeable.rb', line 199
def will_save_change_to_attribute?(attr, **kwargs) attribute_changed?(attr, **kwargs) end