All for Joomla All for Webmasters
Ruby On Rails

Ruby on Rails: Using Observers to listen to object changes

When you’re developing your application, you often need to trigger some actions based on your object changes. For example, let’s suppose that you want to send a notification when your :start_date or :end_date attributes for your Project model are updated. Your first choice would probably be some ActiveRecord callback, like after_update:

The code above works perfectly, but it violates a design principle from SOLID: the single responsibility principle. The Project model is responsible for its relationships, validations and methods; but not for notifying. To do that, we can delegate it to another class using Observer design pattern:


UML diagram for Observer design pattern

ActiveRecord removed the Observer class from its core since 4th Rails version. So, for Rails 4.0 or later, you need to include the gem on your Gemfile and run the bundle command:

To getting started, you should create a observers folder in some directory like app/observers. In the previous example, the after_update callback would be moved to the app/observers/project_observer.rb file:

The method is named exactly as the corresponding callback and receive the observed object as param. It’s also important to notice the “ModelName|Observer” pattern to name the class, so the observer knows which model it should watch. If you choose not to follow the pattern, you should indicate which model should be watched (you can also use one observer for watching more than one model, like this):

After creating your class, you also need to register the observer on your application.rb (don’t forget to restart your server):

Done. That’s all you need for your observer to run. It’s important to keep in mind that observers don’t intervene on object create/update/destroy. So if you use some callback that cancel the object destroy on before_destroy callback for example, it should be placed on your model. The observer should be used only to watch object changes and it’s mostly used for notifying, sending emails and screen asynchronous updates. If you have any doubts or suggestions, please use the comment area or contact me.

You Might Also Like

1 Comment

  • Reply
    December 11th, 2018 at 22:15

    Nice posts! 🙂

  • Leave a Reply