Rick Carlino

Lead software developer and co-founding member @ Farmbot, Inc.

Co-founder @ Fox.Build Makerspace, St. Charles, IL.

Reddit Twitter GitHub LinkedIn Stack Overflow Email Updates

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

July 13 2012

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.

Assumptions

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:

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):

1
2
3
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:

1
config.mongoid.observers = :blog_post_observer

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

1
rails g observer BlogPost

Step 3: Specify callbacks in the observer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class BlogPostObserver < Mongoid::Observer
observe :blog_post
def after_create(blog_post)
BlogNotice.create(info: "New blog created!",
date_of_post: Date.today)
end
def after_destroy(bulletin)
BlogNotice.create(info: "A blog item was destroyed",
date_of_post: Date.today)
end
def after_update(bulletin)
BlogNotice.create(info: "A blog item was updated!",
date_of_post: Date.today)
end
end

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

(C) 2017 Rick Carlino