Overview
En esta guía, puede aprender cómo implementar devoluciones de llamadas en sus modelos Mongoid para personalizar el ciclo de vida de las instancias de sus modelos.
Las devoluciones de llamada son métodos que Mongoid activa en momentos específicos del ciclo de vida de un objeto. Permiten iniciar acciones específicas antes o después de que se modifique el estado de un objeto.
Mongoid implementa muchas de las devoluciones de llamadas de Active Record. Para obtener más información, consulte Devoluciones de llamada en la documentación de Active Record.
Funciones de retorno soportadas
Mongoid admite las siguientes devoluciones de llamadas en clases de modelo que implementan el Módulo de documento:
after_initializeafter_buildbefore_validationafter_validationbefore_createaround_createafter_createafter_findbefore_updatearound_updateafter_updatebefore_upsertaround_upsertafter_upsertbefore_savearound_saveafter_savebefore_destroyaround_destroyafter_destroy
Para obtener más información sobre cualquiera de los tipos de devolución de llamada anteriores, consulte la referencia ActiveRecord::Callbacks en la documentación de la API de Rails.
Puedes implementar funciones de retorno en modelos de documentos tanto de nivel superior como incrustados.
Nota
Comportamiento de invocación de devolución de llamada
Para mayor eficiencia, Mongoid invoca la devolución de llamada solo en el documento donde se realizó la acción de persistencia. Este comportamiento permite a Mongoid admitir jerarquías grandes y gestionar actualizaciones atómicas optimizadas de forma eficiente al no invocar devoluciones de llamada en toda la jerarquía del documento.
Tome precauciones y garantice la capacidad de prueba al implementar devoluciones de llamada para la lógica del dominio, ya que estos diseños pueden generar errores inesperados cuando las devoluciones de llamada en la cadena detienen la ejecución. Recomendamos usar devoluciones de llamada para asuntos transversales ajenos a la funcionalidad principal de su programa, como la puesta en cola de trabajos en segundo plano.
Devoluciones de llamadas de documentos
Se deben implementar y registrar funciones de retorno en las clases de modelos. Puede registrar una función de retorno utilizando métodos ordinarios, bloques y objetos Proc, o definir objetos de función de retorno personalizados que utilicen clases o módulos.
Este ejemplo demuestra cómo registrar funciones de retorno en la clase de modelo Contact de las siguientes maneras:
Incluye el método de clase
before_save, que activa el métodoprocess_phoneantes de guardar una instanciaContacten MongoDB. El métodoprocess_phonese define por separado en la clase.Incluye el método de clase
after_destroyy utiliza un bloque para imprimir un mensaje cuando se elimina una instanciaContact.
class Contact include Mongoid::Document field :name, type: String field :phone, type: String # Creates a callback to clean phone numbers before saving before_save :process_phone protected def process_phone self.phone = phone.gsub(/[^0-9]/, "") if attribute_present?("phone") end # Creates a callback to send a message about object deletion after_destroy do p "deleted the contact for #{name}" end end
El siguiente código realiza operaciones de datos que demuestran las acciones de devolución de llamada:
Contact.create(name: 'Serena Atherton', phone: '999 555-3030') # => `phone` field saved as '9995553030' Contact.create(name: 'Zayba Haq', phone: '999 123?5050') # => `phone` field saved as '9991235050' Contact.first.destroy # => Console message: "deleted the contact for Serena Atherton"
Dado que la funcionalidad de devolución de llamada proviene de Active Support, también puede usar la sintaxis del método de clase set_callback para registrar devoluciones de llamada. El siguiente código muestra cómo usar esta sintaxis para crear una devolución de llamada que almacena los valores originales del campo name en la matriz aliases:
class Contact include Mongoid::Document field :name, type: String field :phone, type: String field :aliases, type: Array, default: [] set_callback(:update, :before) do |document| if document.name_changed? document.push(aliases: document.name_was) end end end Contact.create(name: 'Xavier Bloom', phone: '4447779999') Contact.first.update(name: 'Xav - coworker') # Saved document in MongoDB: # {"aliases":["Xavier Bloom"],"name":"Xav - coworker","phone":"4447779999"}
Funciones de retorno de asociación
Mongoid proporciona las siguientes devoluciones de llamadas de asociación:
after_addafter_removebefore_addbefore_remove
Si registra una devolución de llamada de asociación en su clase de modelo, se invoca siempre que agregue o elimine un documento de cualquiera de las siguientes asociaciones:
embeds_manyhas_manyhas_and_belongs_to_many
Especifique las devoluciones de llamada de asociación como opciones en la asociación correspondiente. Debe pasar el documento añadido o eliminado como parámetro de la devolución de llamada especificada.
El siguiente código demuestra cómo registrar una devolución de llamada de asociación en una clase de modelo User que incorpora múltiples instancias SavedArticle para limitar la cantidad de documentos incorporados para una sola instancia:
class User include Mongoid::Document field :username, type: String # Registers the callback in the association statement embeds_many :saved_articles, before_add: :send_message protected # Passes the association document as a parameter to the callback def send_message(saved_article) if saved_articles.count >= 10 p "you can't save more than 10 articles at a time" throw(:abort) end end end class SavedArticle include Mongoid::Document embedded_in :user field :url, type: String end
Variables locales del hilo
Si ha incrustado documentos secundarios en una asociación con cascade_callbacks: true configurado, las devoluciones de llamada de los documentos secundarios incrustados se ejecutan dentro de una fibra Ruby. Esto significa que, si utiliza Thread#[] Thread#[]= los métodos y para obtener y configurar variables locales de la fibra, dichas devoluciones de llamada no leen ni configuran los valores esperados.
Recomendamos usar los Thread#thread_variable_get Thread#thread_variable_set métodos y para obtener y establecer variables locales del hilo. Para mayor comodidad, Mongoid v9.0.3 introduce los métodos Mongoid::Threaded.get y Mongoid::Threaded.set para implementar esta funcionalidad.
Información Adicional
Para saber cómo evitar que Mongoid ejecute devoluciones de llamadas, consulte las siguientes referencias en la documentación de Active Record:
Para aprender sobre cómo Mongoid gestiona las funciones de retorno en las transacciones, consulta la guía Transacciones y Sesiones.
Para aprender cómo acceder y cambiar sus datos de MongoDB, consulte las guías Interactuar con datos.