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