A Responsibility is a class that provides a single piece of functionality, as per the Single Responsibility Principle. This class provides a single method called "perform", with optional "before" and "after" hooks. It also keeps track of any errors set during execution.
Installation
Add this line to your application's Gemfile:
gem 'responsibility'And then execute:
$ bundle
Or install it yourself as:
$ gem install responsibility
Usage
Define a class, include Responsibility, and define a perform method.
If before is defined and returns false or calls fail! then the perform or after methods will not be run. The same rule applies to perform, and in the case of failure after will not be called.
Any keyword arguments (or just a hash) passed to perform will become attributes of the resulting object
A simple example could be something like:
class UserSignupService
include Responsibility
def before
unless user.present? && user.valid?
errors << "User was not provided or is not valid"
end
end
def perform
user.save
end
def after
UserConfirmationEmailService.perform(email: user.email)
end
end
user = User.new(
email: "cerickbrower@gmail.com",
password: "Wubba Lubba Dub Dub!"
)
result = UserSignupService.perform(user: user)
result.success? #=> true
result.errors #=> []
result.user #=> Our newly persisted userIf errors are created during before, perform, or after then the service fails. In the example above, if the user isn't valid we add an error. In this case the result object would look like:
user = User.new(
email: "",
password: ""
)
result = UserSignupService.perform(user: user)
result.success? #=> false
result.errors #=> ["User was not provided or is not valid"]Another contrived example with an explicit failure, assuming the User object couldn't be persisted:
class UserSignupService
include Responsibility
def before
unless user.present? && user.valid?
errors << "User was not provided or is not valid"
end
end
def perform
unless user.save
fail!(message: "User could not be saved")
end
end
def after
UserConfirmationEmailService.perform(email: user.email)
end
end
result = UserSignupService.perform(user: user)
result.success? #=> false
result.errors #=> ["User could not be saved"]Development
After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/erickbrower/responsibility.