Implementing Observer Pattern in Ruby

Software design patterns help to speed up the development process. These have been proven and tested in this field while resolving specific problems in the best possible way. These patterns are abstract solutions that can be mapped in myriad situations and are classified in the following categories:

  • Behavioral patterns
  • Structural patterns
  • Creational patterns
  • Concurrency patterns

Observer pattern falls in behavioral patterns category. As the pattern name “Observer” suggests that part of code will observe something such as temperature, stock value or a new user registration, etc. The subject of the observation is an entity that runs the process to be observed (such as user registration). Whenever something of interest happens, the subject notifies the Observer about the event. The Observer then process the information and take some action.

This post explains how to implement an observer pattern in Ruby. Additionally, it contains ActiveRecord and Mongoid based implementations to give an idea of its working in Ruby on Rails.

Implementation in Ruby

The class name of the ‘observer’ object is generally created by appending the word ‘Observer’ to the class name of the subject for example, UserObserver or StockObserver. Below is an example in which the file that contains code for StockObserver is named as .

Adding One Observer

Add the following code in file:

Now add the following code in file:

In file, only one observer has been added.

Adding Multiple Observers

For adding multiple observers in file, use the following code:

The output will be:

Creating Observers in Rails using ActiveRecord and Mongoid

Ruby on Rails also provides a way to create observers that requires much less code. For writing observers in Ruby on Rails using ActiveRecord, add the following code:

In Mongoid, just replace with . Rest code will remain the same.

Activation of Observers

In file, you need to register observers. Only registered observers are  activated. This can be done by adding the following line of code to the body of in case of ActiveRecord:

In case of Mongoid, add the following: