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 = {}
    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 [ Document ] document The document to fail. @param [ Symbol ] method The method being called.

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

@since 4.0.0

# File lib/mongoid/persistable.rb, line 91
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)

@param [ Document ] document The document to fail.

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

@since 4.0.0

# File lib/mongoid/persistable.rb, line 76
def fail_due_to_validation!
  raise Errors::Validations.new(self)
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 107
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 208
def persist_atomic_operations(operations)
  if persisted?
    selector = atomic_selector
    _root.collection.find(selector).update(positionally(selector, operations))
  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 187
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 124
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 143
def prepare_atomic_operation
  operations = yield({})
  persist_or_delay_atomic_operation(operations)
  self
end
process_atomic_operations(operations) { |normalized, 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 165
def process_atomic_operations(operations)
  operations.each do |field, value|
    unless attribute_writable?(field)
      raise Errors::ReadonlyAttribute.new(field, value)
    end
    normalized = database_field_name(field)
    yield(normalized, value)
    remove_change(normalized)
  end
end