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 stock_observer.rb.
Adding One Observer
Add the following code in stock.rb file:
#!/usr/bin/ruby load 'stock_observer.rb' class Stock attr_reader :minimum_quantity_limit, :observer attr_accessor :available_quantity#, :observer def initialize(available_quantity, minimum_quantity_limit) @available_quantity = available_quantity @minimum_quantity_limit = minimum_quantity_limit @observer = StockObserver.new end def update_available_quantity(available_quantity) @available_quantity = available_quantity notify_observer end private def notify_observer @observer.notify(self) end s = Stock.new 40,10 puts s.inspect s.update_available_quantity(20) s.update_available_quantity(15) s.update_available_quantity(10) s.update_available_quantity(9) s.update_available_quantity(5) end
Now add the following code in stock_observer.rb file:
class StockObserver def notify(stock) if stock.available_quantity <= stock.minimum_quantity_limit puts "Stock reached minimal limit! Minimum Quantity Limit: #{stock.minimum_quantity_limit} Available Quantity: #{stock.available_quantity}" #Code to send email to purchase dept else puts "Available Quantity: #{stock.available_quantity}" end end end
The output for stock.rb command will be:
Available Quantity: 20 Available Quantity: 15 Stock reached minimal limit! Minimum Quantity Limit: 10 Available Quantity: 10 Stock reached minimal limit! Minimum Quantity Limit: 10 Available Quantity: 9 Stock reached minimal limit! Minimum Quantity Limit: 10 Available Quantity: 5
In stock.rb file, only one observer has been added.
Adding Multiple Observers
For adding multiple observers in stock.rb file, use the following code:
#!/usr/bin/ruby load 'stock_observer.rb' load 'test_observer.rb' class Stock attr_reader :minimum_quantity_limit, :observers attr_accessor :available_quantity def initialize(available_quantity, minimum_quantity_limit) @available_quantity = available_quantity @minimum_quantity_limit = minimum_quantity_limit @observers = [] end def update_available_quantity(available_quantity) @available_quantity = available_quantity notify_observers end def add_observers(*observer_instances) observer_instances.each{|observer_instance| observers << observer_instance} end private def notify_observers observers.each{|observer| observer.notify(self) } end s=Stock.new 40,10 s.add_observers(StockObserver.new, TestObserver.new) puts s.inspect s.update_available_quantity(20) s.update_available_quantity(15) s.update_available_quantity(10) s.update_available_quantity(9) s.update_available_quantity(5) end
The output will be:
Available Quantity: 20 In Test Observer Available Quantity: 15 In Test Observer Stock reached minimal limit! Minimum Quantity Limit: 10 Available Quantity: 10 In Test Observer Stock reached minimal limit! Minimum Quantity Limit: 10 Available Quantity: 9 In Test Observer Stock reached minimal limit! Minimum Quantity Limit: 10 Available Quantity: 5 In Test Observer
This is how custom observers has been created.
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:
class StockObserver < ActiveRecord::Observer def after_update(stock) if stock.quantity <= stock.minial_limit #send email code here end end end
In Mongoid, just replace ActiveRecord::Observer with Mongoid::Observer. Rest code will remain the same.
Activation of Observers
In config/application.rb 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 class Application < Rails::Application in file application.rb in case of ActiveRecord:
config.active_record.observers = :stock_observer, :registration_observer
In case of Mongoid, add the following:
config.mongoid.observers = :stock_observer, :registration_observer
0 Comments