Rick Carlino

Personal blog of FarmBot co-founder Rick Carlino.

Covering Open Source news, history and best practices.

Stack Overflow Reddit Github Linkedin Twitter

[ 💬 Contact ] [ 👤 About ] [ 📰 Recent Reading ] [ ✉️ Subscribe ]

So you want to make an observer in Mongoid...

UPDATE: Rails 4 has removed support for observers. As such, they have been discontinued in Mongoid. See this issue on github for more information.

Greetings, folks! Long time no see, and as such I thought it would be fitting to give back to the community and type up a quick tutorial. Recently, I came across the need to create an activity stream on a mongoid project that encompassed multiple models and events. An observer seemed like the best solution because of the complex nature of the project. I decided to make a quick write up for anyone else who is confronted with the task.


For this tutorial, I will assume you have a basic understanding of Rails, Mongoid and Ruby. I will not go through the steps required to create an application, nor will I explain how to process models into meaningful output once they are created.

A little bit about observers

As the name would suggest, an observer “observes” models, using a variety of callbacks such as:

  • after_initialize
  • after_build
  • before_validation
  • after_validation
  • before_create
  • around_create
  • after_create
  • before_update
  • around_update
  • after_update
  • before_save
  • around_save
  • after_save
  • before_destroy
  • around_destroy
  • after_destroy

If you have the need to do something before/during/after a model is created/updated/initialized/destroyed, an observer may be a good solution.

Step 1: Create appropriate models.

Lets generate some simple models in console to work with for this tutorial. One is the model to be observed (BlogPost), while the other is the model that we will use to log events that relate to BlogPost (BlogNotice):

rails g model BlogPost title:String body:String date_of_post:Date

rails g model BlogNotice info:String date_of_post:Date

Now that we have a lonely BlogPost model in our application, let’s pretend that somewhere in our site we want to create a list of notices every time a BlogPost is created. We will do this by storing records in the BlogNotice model.


Step 2: Modify config/application.rb and generate an observer

Add a new line to  application.rb to read:

config.mongoid.observers = :blog_post_observer

Then generate the observer using the following command (observers are named after the model they observe):

rails g observer BlogPost

Step 3: Specify callbacks in the observer

class BlogPostObserver < Mongoid::Observer
    observe :blog_post

    def after_create(blog_post)
      BlogNotice.create(info: "New blog created!",
                        date_of_post: Date.today)

    def after_destroy(bulletin)
      BlogNotice.create(info: "A blog item was destroyed",
                        date_of_post: Date.today)

    def after_update(bulletin)
      BlogNotice.create(info: "A blog item was updated!",
                        date_of_post: Date.today)


…and that’s it! Feel free to comment if you have any questions.