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