module Mongoid::Persistable
Contains general behaviour for persistence operations.
@since 2.0.0
Public Instance Methods
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 51 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
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 87 def fail_due_to_callback!(method) raise Errors::Callback.new(self.class, method) end
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 72 def fail_due_to_validation! raise Errors::Validations.new(self) end
Private Instance Methods
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 103 def executing_atomically? !@atomic_updates_to_execute.nil? end
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) selector = atomic_selector _root.collection.find(selector).update(positionally(selector, operations)) end
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 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 120 def post_process_persist(result, options = {}) post_persist unless result == false errors.clear unless performing_validations?(options) true end
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 139 def prepare_atomic_operation # @todo: Check if the document is persisted here. operations = yield({}) persist_or_delay_atomic_operation(operations) self end
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| normalized = database_field_name(field) yield(normalized, value) remove_change(normalized) end end