123456789_123456789_123456789_123456789_123456789_

Module: Mongoid::Touchable::InstanceMethods

Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Included In:
Defined in: lib/mongoid/touchable.rb

Overview

TODO:

Refactor using ActiveSupport::Concern

Used to provide mixin functionality.

Instance Attribute Summary

Instance Method Summary

Instance Attribute Details

#_touchable_parent?Boolean (readonly)

This method is for internal use only.

Indicates whether the parent exists and is touchable.

[ GitHub ]

  
# File 'lib/mongoid/touchable.rb', line 113

def _touchable_parent?
  _parent && _association&.inverse_association&.touchable?
end

#touch_callbacks_suppressed?true | false (readonly)

This method is for internal use only.

Queries whether touch callbacks are being suppressed for the class that includes this module.

Returns:

  • (true | false)

    Whether touch callbacks are suppressed.

[ GitHub ]

  
# File 'lib/mongoid/touchable.rb', line 32

def touch_callbacks_suppressed?
  Touchable.touch_callbacks_suppressed?(self.class.name)
end

Instance Method Details

#_clear_touch_updates(field = nil)

This method is for internal use only.

Clears changes for the model caused by touch operation.

Parameters:

  • field (Symbol) (defaults to: nil)

    The name of an additional field to update.

[ GitHub ]

  
# File 'lib/mongoid/touchable.rb', line 93

def _clear_touch_updates(field = nil)
  remove_change(:updated_at)
  remove_change(field) if field
  _parent._clear_touch_updates if _touchable_parent?
end

#_extract_touches_from_atomic_sets(field = nil) ⇒ Hash (private)

This method is for internal use only.

Extract and remove the atomic updates for the touch operation(s) from the currently enqueued atomic $set operations.

Parameters:

  • field (Symbol) (defaults to: nil)

    The optional field.

Returns:

  • (Hash)

    The field-value pairs to update atomically.

[ GitHub ]

  
# File 'lib/mongoid/touchable.rb', line 127

def _extract_touches_from_atomic_sets(field = nil)
  updates = atomic_updates['$set']
  return {} unless updates

  touchable_keys = Set['updated_at', 'u_at']
  touchable_keys << field.to_s if field.present?

  updates.keys.each_with_object({}) do |key, touches|
    if touchable_keys.include?(key.split('.').last)
      touches[key] = updates.delete(key)
    end
  end
end

#_gather_touch_updates(now, field = nil) ⇒ Hash<String, Time>

This method is for internal use only.

Recursively sets touchable fields on the current document and each of its parents, including the root node. Returns the combined atomic $set operations to be performed on the root document.

Parameters:

  • now (Time)

    The timestamp used for synchronizing the touched time.

  • field (Symbol) (defaults to: nil)

    The name of an additional field to update.

Returns:

  • (Hash<String, Time>)

    The touch operations to perform as an atomic $set.

[ GitHub ]

  
# File 'lib/mongoid/touchable.rb', line 75

def _gather_touch_updates(now, field = nil)
  return if touch_callbacks_suppressed?

  field = database_field_name(field)

  write_attribute(:updated_at, now) if respond_to?("updated_at=")
  write_attribute(field, now) if field.present?

  touches = _extract_touches_from_atomic_sets(field) || {}
  touches.merge!(_parent._gather_touch_updates(now) || {}) if _touchable_parent?
  touches
end

#_run_touch_callbacks_from_root

This method is for internal use only.

Recursively runs :touch callbacks for the document and its parents, beginning with the root document and cascading through each successive child document.

[ GitHub ]

  
# File 'lib/mongoid/touchable.rb', line 104

def _run_touch_callbacks_from_root
  return if touch_callbacks_suppressed?
  _parent._run_touch_callbacks_from_root if _touchable_parent?
  run_callbacks(:touch)
end

#suppress_touch_callbacks

This method is for internal use only.

Suppresses the invocation of touch callbacks, for the class that includes this module, for the duration of the block.

Examples:

Suppress touch callbacks on Person documents:

person.suppress_touch_callbacks { ... }
[ GitHub ]

  
# File 'lib/mongoid/touchable.rb', line 22

def suppress_touch_callbacks
  Touchable.suppress_touch_callbacks(self.class.name) { yield }
end

#touch(field = nil) ⇒ true/false

Note:

This will not autobuild associations if those options are set.

Touch the document, in effect updating its updated_at timestamp and optionally the provided field to the current time. If any belongs_to associations exist with a touch option, they will be updated as well.

Examples:

Update the updated_at timestamp.

document.touch

Update the updated_at and provided timestamps.

document.touch(:audited)

Parameters:

  • field (Symbol) (defaults to: nil)

    The name of an additional field to update.

Returns:

  • (true/false)

    false if document is new_record otherwise true.

[ GitHub ]

  
# File 'lib/mongoid/touchable.rb', line 51

def touch(field = nil)
  return false if _root.new_record?

  begin
    touches = _gather_touch_updates(Time.current, field)
    _root.send(:persist_atomic_operations, '$set' => touches) if touches.present?
    _run_touch_callbacks_from_root
  ensure
    _clear_touch_updates(field)
  end

  true
end