Docs Menu
Docs Home
/ / /
Mongoid
/

Callbacks

On this page

  • Overview
  • Supported Callbacks
  • Document Callbacks
  • Association Callbacks
  • Additional Information

In this guide, you can learn how to implement callbacks in your Mongoid models to customize the life cycle of your model instances.

Callbacks are methods that Mongoid triggers at specified moments of an object's life cycle. They allow you to initiate specified actions before or after changes to an object's state.

Mongoid implements many of the callbacks from Active Record. To learn more, see Callbacks in the Active Record documentation.

Mongoid supports the following callbacks on model classes that implement the 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

To learn more about any of the preceding callback types, see the ActiveRecord::Callbacks reference in the Rails API documentation.

You can implement callbacks in both top-level and embedded document models.

Note

Callback Invocation Behavior

For efficiency, Mongoid invokes the callback only on the document that you performed the persistence action on. This behavior enables Mongoid to support large hierarchies and handle optimized atomic updates efficiently by not invoking callbacks throughout the document hierarchy.

Take precautions and ensure testability when implementing callbacks for domain logic, because these designs can lead to unexpected errors when callbacks in the chain halt execution. We recommend using callbacks for cross-cutting concerns outside of your program's core functionality, such as queueing up background jobs.

You must implement and register callbacks on your model classes. You can register a callback by using ordinary methods, blocks and Proc objects, or by defining custom callback objects that use classes or modules.

This example demonstrates how to register callbacks on the Contact model class in the following ways:

  • Includes the before_save class method, which triggers the process_phone method before a Contact instance is saved to MongoDB. The process_phone method is defined separately in the class.

  • Includes the after_destroy class method and uses a block to print a message when a Contact instance is deleted.

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

The following code performs data operations that demonstrate the callback actions:

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"

Because callback functionality comes from Active Support, you can alternatively use the set_callback class method syntax to register callbacks. The following code demonstrates how to use this syntax to create a callback that stores original values of the name field in the aliases array:

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 provides the following association callbacks:

  • after_add

  • after_remove

  • before_add

  • before_remove

If you register an association callback on your model class, it is invoked whenever you add or remove a document from any of the following associations:

  • embeds_many

  • has_many

  • has_and_belongs_to_many

Specify association callbacks as options on the respective association. You must pass the added or removed document as the parameter to the specified callback.

The following code demonstrates how to register an association callback on a User model class that embeds multiple SavedArticle instances to limit the number of embedded documents for a single instance:

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

To learn how to prevent Mongoid from running callbacks, see the following references in the Active Record documentation:

To learn about how Mongoid manages callbacks in transactions, see the Transactions and Sessions guide.

To learn how to access and change your MongoDB data, see the Interact with Data guides.

Back

Document Validation