Homie
Welcome!
Those of you who know why and when we need the Observer pattern will definitely find this gem useful. Those of you who don't, should read about the Observer pattern and return here afterward.
Ruby has a default module called Observable that reflect same idea but doesn't have such flexibility as Homie.
Homie will do the dirty work for you. It will call and execute all required logic sequentially. All you need is to:
- consider Homie syntax
- decompose the logic into the
subjectandobserversbound to particular events - broadcast those events when they happen
Installation
Add this line to your application's Gemfile:
gem 'homie'
And then execute:
$ bundle
Or install it yourself as:
$ gem install homie
Usage
About
To implement Observer pattern and start using Homie first you should decompose logic into 2 object types:
Subject- the main part of logic, depending on the results of which the further part of logic should vary between scenarios.Observer- those scenarios that will be executed depending on the Subject result.
Include into your Subject Homie module
include Homie
Subscribing
Bind Observers to your Subject on particular events. As an Observer it could be any object with a call method(that is an entry point for business logic) OR a block of code.
To bind Observer use method on(event_name, Observer).
You have 2 options, how you could bind your observers:
- When you want to incapsulate those observers. ```ruby class UserCreator include Homie
def initialize(params) @params = params
self.on(:succeeded, StatistictsGenerator.new)
self.on(:succeeded) { |user| EmailPublisher.send_email(user) }
end end
*Your observers should repeat signature of params passing by Subject in their method call or in a block of code.*
* When incapsulation don't bother you **OR** you need to apply a closure for some context/method execution.
```ruby
class UsersController < ApplicationController
def create
UserCreator.new(params).
on(:succeeded) do |user|
render json: user, status: 201
end.
on(:failed) do |user|
render json: user.errors, status: 422
end.call
end
end
Subscribing supports chaining.
Broadcasting
To broadcast an event use method broadcast(event_name, *arguments).
Broadcasting also support chaining.
class UserCreator
include Homie
def initialize(params)
@params = params
end
def call
user = User.create!(@params)
broadcast :succeeded, user
rescue ActiveRecord::RecordInvalid => invalid
broadcast :failed, invalid.record
end
end
You can incapsulate broadcasting of events or make public method calls as well.
I support the theory that says that two events are usually enough: succeeded or failed.
I have made shortcuts for these cases.
So
broadcast :succeeded, user is equal to succeeded(user)
and
broadcast :failed, user is equal to failed(user).
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/donasktello/homie. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
License
The gem is available as open source under the terms of the MIT License.