module Mongoid::Persistable

def _mongoid_atomic_context_changed_fields

Returns:
  • (Array) - The changed fields.

Other tags:
    Example: Return the current atomic context's changed fields. -

Other tags:
    Api: - private
def _mongoid_atomic_context_changed_fields
  @atomic_context.values.flat_map(&:keys)
end

def _mongoid_pop_atomic_context

Other tags:
    Example: Pop an atomic context off the stack. -

Other tags:
    Api: - private
def _mongoid_pop_atomic_context
  return unless executing_atomically?
  @atomic_updates_to_execute_stack.pop
  @atomic_context = @atomic_updates_to_execute_stack.last
end

def _mongoid_push_atomic_context

Other tags:
    Example: Push a new atomic context onto the stack. -

Other tags:
    Api: - private
def _mongoid_push_atomic_context
  return unless executing_atomically?
  @atomic_context = {}
  @atomic_updates_to_execute_stack << @atomic_context
end

def _mongoid_remove_atomic_context_changes

Other tags:
    Example: Remove the current atomic context's dirty changes. -

Other tags:
    Api: - private
def _mongoid_remove_atomic_context_changes
  return unless executing_atomically?
  _mongoid_atomic_context_changed_fields.each { |f| remove_change f }
end

def _mongoid_reset_atomic_context_changes!

Other tags:
    Example: Reset the current atomic context's changed attributes. -

Other tags:
    Api: - private
def _mongoid_reset_atomic_context_changes!
  return unless executing_atomically?
  _mongoid_atomic_context_changed_fields.each { |f| reset_attribute! f }
end

def atomically(join_context: nil)

Returns:
  • (true | false) - If the operation succeeded.

Parameters:
  • join_context (true | false) -- Join the context (i.e. merge

Other tags:
    Example: Execute some inner operations atomically, but independently from the outer operations. -
    Example: Execute the operations atomically. -
def atomically(join_context: nil)
  join_context = Mongoid.join_contexts if join_context.nil?
  call_depth = @atomic_depth ||= 0
  has_own_context = call_depth.zero? || !join_context
  @atomic_updates_to_execute_stack ||= []
  _mongoid_push_atomic_context if has_own_context
  if block_given?
    @atomic_depth += 1
    yield(self)
    @atomic_depth -= 1
  end
  if has_own_context
    persist_atomic_operations @atomic_context
    _mongoid_remove_atomic_context_changes
  end
  true
rescue Exception => e
  _mongoid_reset_atomic_context_changes! if has_own_context
  raise e
ensure
  _mongoid_pop_atomic_context if has_own_context
  if call_depth.zero?
    @atomic_depth = nil
    @atomic_updates_to_execute_stack = nil
  end
end

def executing_atomically?

Returns:
  • (true | false) - If we are current executing atomically.

Other tags:
    Example: Are we executing atomically? -

Other tags:
    Api: - private
def executing_atomically?
  !@atomic_updates_to_execute_stack.nil?
end

def fail_due_to_callback!(method)

Raises:
  • (Errors::Callback) - The callback error.

Parameters:
  • method (Symbol) -- The method being called.

Other tags:
    Example: Raise the callback error. -
def fail_due_to_callback!(method)
  raise Errors::Callback.new(self.class, method)
end

def fail_due_to_validation!

Raises:
  • (Errors::Validations) - The validation error.

Other tags:
    Example: Raise the validation error. -
def fail_due_to_validation!
  raise Errors::Validations.new(self)
end

def persist_atomic_operations(operations)

Parameters:
  • operations (Hash) -- The atomic operations.

Other tags:
    Example: Persist the atomic operations. -

Other tags:
    Api: - private
def persist_atomic_operations(operations)
  if persisted? && operations && !operations.empty?
    selector = atomic_selector
    _root.collection.find(selector).update_one(positionally(selector, operations), session: _session)
  end
end

def persist_or_delay_atomic_operation(operation)

Parameters:
  • operation (Hash) -- The operation.

Other tags:
    Example: Persist immediately or delay the operations. -

Other tags:
    Api: - private
def persist_or_delay_atomic_operation(operation)
  if executing_atomically?
    operation.each do |(name, hash)|
      @atomic_context[name] ||= {}
      @atomic_context[name].merge!(hash)
    end
  else
    persist_atomic_operations(operation)
  end
end

def post_process_persist(result, options = {})

Returns:
  • (true) - true.

Options Hash: (**options)
  • :validate (true | false) -- Whether or not to validate.

Parameters:
  • options (Hash) -- The options.
  • result (Object) -- The result of the operation.

Other tags:
    Example: Post process the persistence operation. -

Other tags:
    Api: - private
def post_process_persist(result, options = {})
  post_persist unless result == false
  errors.clear unless performing_validations?(options)
  true
end

def prepare_atomic_operation

Returns:
  • (Object) - The result of the operation.

Other tags:
    Example: Prepare the atomic operation. -

Other tags:
    Api: - private
def prepare_atomic_operation
  raise Errors::ReadonlyDocument.new(self.class) if readonly? && !Mongoid.legacy_readonly
  operations = yield({})
  persist_or_delay_atomic_operation(operations)
  self
end

def process_atomic_operations(operations)

Returns:
  • (Hash) - The operations.

Parameters:
  • operations (Hash) -- The atomic operations.

Other tags:
    Example: Process the atomic operations. -

Other tags:
    Api: - private
def process_atomic_operations(operations)
  operations.each do |field, value|
    access = database_field_name(field)
    yield(access, value)
    remove_change(access) unless executing_atomically?
  end
end