Understanding Observers in Ruby on Rails

afaq_shahid

Afaq Shahid Khan

Posted on June 20, 2024

Understanding Observers in Ruby on Rails

As your Ruby on Rails application grows, maintaining clean and manageable code becomes increasingly important. One of the powerful yet often underutilized features in Rails is the Observer pattern. Observers allow you to keep your models lean by extracting responsibilities that don't necessarily belong in the model itself. In this article, we'll explore what observers are, when to use them, and how to implement them in your Rails application.

What are Observers?

Observers in Rails provide a way to respond to lifecycle callbacks outside of your models. They allow you to encapsulate the callback logic in a separate class, promoting cleaner and more modular code. Observers listen for changes to an object and respond to those changes without the object needing to explicitly notify the observer.

When to Use Observers

Observers are ideal for situations where you want to decouple the callback logic from your models. Here are a few common use cases:

  1. Logging and Analytics: Track changes or actions performed on a model without cluttering the model code.
  2. Notifications: Send emails, Slack messages, or other notifications when certain model events occur.
  3. Asynchronous Jobs: Enqueue background jobs in response to model changes.
  4. Complex Business Logic: Implement business rules that should be applied after certain model changes.

Implementing Observers in Rails

Rails observers are not included in Rails by default anymore, starting from Rails 4. However, you can still use them by including the rails-observers gem in your Gemfile:

gem 'rails-observers'
Enter fullscreen mode Exit fullscreen mode

After adding the gem, run bundle install to install it.

Creating an Observer

Let’s walk through an example of creating an observer. Imagine you have a User model and you want to send a welcome email whenever a new user is created.

  1. Generate the Observer:

First, generate the observer file:

   rails generate observer User
Enter fullscreen mode Exit fullscreen mode

This will create a file app/models/user_observer.rb.

  1. Define the Observer:

Open the generated user_observer.rb file and define the callback methods:

   class UserObserver < ActiveRecord::Observer
     def after_create(user)
       UserMailer.welcome_email(user).deliver_later
     end
   end
Enter fullscreen mode Exit fullscreen mode

Here, after_create is a callback method that will be triggered after a new user is created. The UserMailer.welcome_email(user).deliver_later line enqueues the welcome email to be sent asynchronously.

  1. Register the Observer:

To make Rails aware of the observer, you need to register it. Open config/application.rb and add the following line inside the class Application < Rails::Application block:

   config.active_record.observers = :user_observer
Enter fullscreen mode Exit fullscreen mode
  1. Create the Mailer:

If you haven't already, generate the mailer:

   rails generate mailer UserMailer
Enter fullscreen mode Exit fullscreen mode

Define the welcome_email method in app/mailers/user_mailer.rb:

   class UserMailer < ApplicationMailer
     def welcome_email(user)
       @user = user
       mail(to: @user.email, subject: 'Welcome to My Awesome Site')
     end
   end
Enter fullscreen mode Exit fullscreen mode

Also, create a view template for the email in app/views/user_mailer/welcome_email.html.erb.

Benefits of Using Observers

  • Separation of Concerns: By moving callback logic to observers, your models remain focused on their primary responsibility: data persistence and validation.
  • Reusability: Observers can be reused across different models, promoting DRY (Don't Repeat Yourself) principles.
  • Maintainability: With a clean separation of callback logic, your codebase becomes easier to maintain and understand.

Conclusion

Observers are a powerful tool in the Rails ecosystem for maintaining clean and modular code. By decoupling callback logic from your models, you can achieve a more maintainable and scalable codebase. While Rails no longer includes observers by default, the rails-observers gem makes it easy to integrate this pattern into your application. Use observers to handle logging, notifications, complex business logic, and more, ensuring your models remain lean and focused on their primary responsibilities.

Happy coding!

💖 💪 🙅 🚩
afaq_shahid
Afaq Shahid Khan

Posted on June 20, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related