module Mongoid::Persistable

Contains general behaviour for persistence operations.

@since 2.0.0

Constants

LIST_OPERATIONS

The atomic operations that deal with arrays or sets in the db.

@since 4.0.0

Public Instance Methods

atomically() { |self| ... } click to toggle source

Execute operations atomically (in a single database call) for everything that would happen inside the block.

@example Execute the operations atomically.

document.atomically do
  document.set(name: "Tool").inc(likes: 10)
end

@return [ true, false ] If the operation succeeded.

@since 4.0.0

# File lib/mongoid/persistable.rb, line 55
def atomically
  begin
    @atomic_updates_to_execute = @atomic_updates_to_execute || {}
    yield(self) if block_given?
    persist_atomic_operations(@atomic_updates_to_execute)
    true
  ensure
    @atomic_updates_to_execute = nil
  end
end
fail_due_to_callback!(method) click to toggle source

Raise an error if a callback failed.

@example Raise the callback error.

Person.fail_due_to_callback!(person, :create!)

@param [ Symbol ] method The method being called.

@raise [ Errors::Callback ] The callback error.

@since 4.0.0

# File lib/mongoid/persistable.rb, line 88
def fail_due_to_callback!(method)
  raise Errors::Callback.new(self.class, method)
end
fail_due_to_validation!() click to toggle source

Raise an error if validation failed.

@example Raise the validation error.

Person.fail_due_to_validation!(person)

@raise [ Errors::Validations ] The validation error.

@since 4.0.0

# File lib/mongoid/persistable.rb, line 74
def fail_due_to_validation!
  raise Errors::Validations.new(self)
end
hasherizer(keys, value) click to toggle source
# File lib/mongoid/persistable/settable.rb, line 45
def hasherizer(keys, value)
  return value if keys.empty?
  {}.tap { |hash| hash[keys.shift] = hasherizer(keys, value) }
end

Private Instance Methods

executing_atomically?() click to toggle source

Are we executing an atomically block on the current document?

@api private

@example Are we executing atomically?

document.executing_atomically?

@return [ true, false ] If we are current executing atomically.

@since 4.0.0

# File lib/mongoid/persistable.rb, line 104
def executing_atomically?
  !@atomic_updates_to_execute.nil?
end
persist_atomic_operations(operations) click to toggle source

Persist the atomic operations.

@api private

@example Persist the atomic operations.

persist_atomic_operations(ops)

@param [ Hash ] operations The atomic operations.

@since 4.0.0

# File lib/mongoid/persistable.rb, line 202
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
persist_or_delay_atomic_operation(operation) click to toggle source

If we are in an atomically block, add the operations to the delayed group, otherwise persist immediately.

@api private

@example Persist immediately or delay the operations.

document.persist_or_delay_atomic_operation(ops)

@param [ Hash ] operation The operation.

@since 4.0.0

# File lib/mongoid/persistable.rb, line 181
def persist_or_delay_atomic_operation(operation)
  if executing_atomically?
    operation.each do |(name, hash)|
      @atomic_updates_to_execute[name] ||= {}
      @atomic_updates_to_execute[name].merge!(hash)
    end
  else
    persist_atomic_operations(operation)
  end
end
post_process_persist(result, options = {}) click to toggle source

Post process the persistence operation.

@api private

@example Post process the persistence operation.

document.post_process_persist(true)

@param [ Object ] result The result of the operation. @param [ Hash ] options The options.

@return [ true ] true.

@since 4.0.0

# File lib/mongoid/persistable.rb, line 121
def post_process_persist(result, options = {})
  post_persist unless result == false
  errors.clear unless performing_validations?(options)
  true
end
prepare_atomic_operation() { |{}| ... } click to toggle source

Prepare an atomic persistence operation. Yields an empty hash to be sent to the update.

@api private

@example Prepare the atomic operation.

document.prepare_atomic_operation do |coll, selector, opts|
  ...
end

@return [ Object ] The result of the operation.

@since 4.0.0

# File lib/mongoid/persistable.rb, line 140
def prepare_atomic_operation
  operations = yield({})
  persist_or_delay_atomic_operation(operations)
  self
end
process_atomic_operations(operations) { |access, value| ... } click to toggle source

Process the atomic operations - this handles the common behaviour of iterating through each op, getting the aliased field name, and removing appropriate dirty changes.

@api private

@example Process the atomic operations.

document.process_atomic_operations(pulls) do |field, value|
  ...
end

@param [ Hash ] operations The atomic operations.

@return [ Hash ] The operations.

@since 4.0.0

# File lib/mongoid/persistable.rb, line 162
def process_atomic_operations(operations)
  operations.each do |field, value|
    access = database_field_name(field)
    yield(access, value)
    remove_change(access)
  end
end