No commit activity in last 3 years
No release in over 3 years
A Ruby library to organize the code
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 2.1
~> 13.0
~> 3.0
 Project Readme

SingleActionService

Gem Version

Implementation of a Service Object pattern in Ruby.

Installation

Add this line to your application's Gemfile:

gem 'single_action_service'

And then execute:

$ bundle

Or install it yourself as:

$ gem install single_action_service

Usage

Create an inheritor from a SingleActionService::Base with a single method named call

class Summator < SingleActionService::Base
  def call
  end
end

Create a constructor with parameters

class Summator < SingleActionService::Base
  def initialize(x, y)
    @x = x
    @y = y
  end
end

or pass them to the call method

class Summator < SingleActionService::Base
  def call(x, y)
  end
end

Perform the action and return the result by calling success(data = nil)

class Summator < SingleActionService::Base
  def call(x, y)
    sum = x + y
    success(sum)
  end
end

or return the error based on the validations by calling error(data: nil, code: nil)

class Summator < SingleActionService::Base
  NIL_NUMBERS_ERROR = :nil_numbers_error

  def call(x, y)
    if x.nil? || y.nil?
      return error(code: NIL_NUMBERS_ERROR)
    end
  end
end

Call the service and process a result

summator = Summator.new
result = summator.call(1, 2)

if result.success?
  result.data
else
  result.error_code
end

Or you can use a data! method if you want to throw an exception when an error has occurred:

begin
  result = Summator.new.call(1, 2).data!
rescue SingleActionService::InvalidResult => e
  e.result.error_code
end

You can define a list of errors of a service by calling a self.errors(errors_data) method.
For each error, a method #{error_name}_error(data = nil) will be generated to instantiate the result with the appropriate code and optional data:

class Summator < SingleActionService::Base
  errors [
    { name: :nil_numbers, code: :nil_numbers_error }
  ]

  def call(x, y)
    if x.nil? || y.nil?
      return nil_numbers_error
    end
  end
end

You can check for the specific error calling an autogenerated checking method of the result:

result = Summator.new.call(nil, nil)
result.nil_numbers_error? # true

API Reference

SingleActionService::Base

A base class for services. Create an inheritor from him to use it. Methods:

Name Description
success(data = nil) Returns a successful SingleActionService::Result with
data passed in arguments.
error(data: nil, code: nil) Returns an error SingleActionService::Result with
data and the error code passed in arguments.
#{error_name}_error(data = nil) Autogenerated method to create an error result
with the specific error code
without having to pass it in arguments.
Generated for each error passed to the self.errors method.
Returns an error SingleActionService::Result with
data passed to arguments.
self.errors(errors_data) Call this method to identify possible service errors.
Accepts an array of objects:
{ name: :error_name, code: :error_code }

SingleActionService::Result

A base class for the result that the service returns. Instantiated by service methods such as success, error and autogenerated error methods. Methods:

Name Description
success? Call this method to check the result for success.
Returns true for successful results created by the
success method of a service.
error? Call this method to check the result for error.
Returns false for error results created by the
error method of a service or by autogenerated
error methods.
#{error_name}_error? Call this method to check the result for the specific error.
Autogenerated for each error passed to the self.errors
of a service.
data Returns data passed to the result instantiation method
data! Returns data passed to the result instantiation method.
Throws a SingleActionService::InvalidResult
exception if the result contains an error.

SingleActionService::InvalidResult

An exception thrown by the data! method of a result. Methods:

Name Description
result Returns a SingleActionService::Result

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/sequenia/single_action_service. 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.