Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /

Personalizar las funciones de devolución de llamada para los modelos

En esta guía, puedes aprender cómo implementar retrollamadas en tus modelos Mongoid para personalizar el ciclo de vida de tus instancias de modelo.

Los callbacks 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 cambios en el estado de un objeto.

Mongoid implementa muchas de las devoluciones de llamada provenientes de Active Record. Para obtener más información, consulte función de retorno en la documentación de Active Record.

Mongoid admite las siguientes devoluciones de llamadas en clases de modelo que implementan el Document module:

  • after_initialize

  • after_build

  • before_validation

  • after_validation

  • before_create

  • around_create

  • after_create

  • after_find

  • before_update

  • around_update

  • after_update

  • before_upsert

  • around_upsert

  • after_upsert

  • before_save

  • around_save

  • after_save

  • before_destroy

  • around_destroy

  • after_destroy

Para obtener más información sobre cualquiera de los tipos de callback anteriores, consulta 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 función de retorno únicamente en el documento sobre el cual se realizó la acción de persistencia. Este comportamiento permite que Mongoid admita grandes jerarquías y gestione actualizaciones atómicas optimizadas de manera eficiente al no invocar callbacks en toda la jerarquía del documento.

Toma precauciones y asegúrate de la capacidad de prueba al implementar funciones de retorno para lógica de dominio, ya que estos diseños pueden llevar a errores inesperados cuando las funciones de retorno en la cadena detienen la ejecución. Recomendamos usar funciones de retorno para preocupaciones transversales fuera de la funcionalidad principal de tu programa, como la cola de tareas en segundo plano.

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étodo process_phone antes de que se guarde una instancia Contact en MongoDB. El método process_phone se define por separado en la clase.

  • Incluye el método de clase after_destroy y utiliza un bloque para imprimir un mensaje cuando se elimina una instancia Contact.

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"

Como la funcionalidad de callbacks proviene de Active Support, también se puede usar la sintaxis del método de clase set_callback para registrar callbacks. El siguiente código demuestra cómo utilizar esta sintaxis para crear una función de retorno que almacene los valores originales del campo name en el arreglo 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"}

Mongoid proporciona las siguientes devoluciones de llamadas de asociación:

  • after_add

  • after_remove

  • before_add

  • before_remove

Si registras una función de retorno de asociación en tu clase de modelo, se invoca cada vez que agregas o remueves un documento de cualquiera de las siguientes asociaciones:

  • embeds_many

  • has_many

  • has_and_belongs_to_many

Especifica los callbacks de asociación como opciones en la asociación correspondiente. Debes pasar el documento añadido o eliminado como parámetro a la función de retorno especificada.

El siguiente código demuestra cómo registrar una función de retorno de asociación en una clase de modelo User que incrusta varias instancias de SavedArticle para limitar el número de documentos incrustados 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

Si tienes documentos secundarios incrustados en una asociación que tiene cascade_callbacks: true configurado, entonces las devoluciones de llamada secundarias incrustadas se ejecutan dentro de un Fiber Ruby. Esto significa que, si utilizas los métodos Thread#[] y Thread#[]= para obtener y establecer variables locales de fibra, esas funciones de retorno no leen ni establecen los valores que esperas.

Recomendamos utilizar los métodos Thread#thread_variable_get y Thread#thread_variable_set para obtener y establecer variables verdaderamente locales de subproceso. Para mayor comodidad, Mongoid v9.0.3 introduce los métodos Mongoid::Threaded.get y Mongoid::Threaded.set para implementar esta funcionalidad.

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 a acceder y modificar tus datos en MongoDB, consulta las guías de Interacción con Datos.

Volver

particionado

En esta página