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

4 Comments

  • Reply
    Sannytet
    December 11th, 2018 at 22:15

    Nice posts! 🙂
    ___
    Sanny

  • Reply
    John Goldman
    December 27th, 2018 at 18:35

    thank you so much!

  • Reply
    Gaurav Tinkhede
    May 10th, 2020 at 09:26

    Hi ,
    I am new to rails and want to use observer for auditing in my project.
    I am facing below error :

    method_missing': undefined method observers=’ for ActiveRecord::Base:Class (NoMethodError)

    Regards,
    Gaurav

    • Reply
      Ronan Lopes
      May 10th, 2020 at 15:45

      Hi, Gaurav! You probably missed something in the middle. Rails doesn’t have observers enabled by default lately, so you would have to add the gem ‘rails-observers’ and run the bundle command. Also, after add that config to your application.rb, you have to restart your server. Give those a try. Good luck there!

    Leave a Reply to John Goldman Cancel Reply