Skip to content
Service Object based on Either Monad
Ruby
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
lib
spec
.gitignore
.rspec
.rubocop.yml
Gemfile
LICENSE.txt
README.md
Rakefile
circle.yml
operators-service.gemspec

README.md

Operators::Service

Gem Version CircleCI Maintainability

Operators::Service is a lightweight implementation of Service Object based on Either Monad. That gives an home of application business logic.

Service Objects are created when an action:

  • Uses integration with external services

  • Uses several models

  • Is complex (such as calculating sales statistics)

Installation

Add this line to your application's Gemfile:

gem 'operators-service'

And then execute:

$ bundle

Or install it yourself as:

$ gem install operators-service

Usage

class UserCreator < Operators::Service
  attr_reader :params
  
  def initialize(params)
    @params = params
  end

  def call
    user = User.create(params)
    if !user.new_record?
      success(user)
    else
      failure(user.errors)
    end
  end
end

success - returns instance of Dry::Monads::Either::Right

failure - returns instance of Dry::Monads::Either::Left

class UsersController < ApplicationController
  def create
    UserCreator.call(user_params).fmap do |user|
      render json: user
    end.or_fmap do |errors|
      render json: errors.full_messages
    end
  end
  
  private
  
  def user_params
    params.require(:user).permit!
  end
end

More complicated usage

If you need rescue_callbacks then you should define calling instead of call.

class Auth < Operators::Service
  rescue_callbacks AuthError, CredentialsError

  def initialize(options)
    @options = options
  end

  def calling
    return failure('User already authed') if @options[:failure] # returns Dry::Monads::Left('User already authed')

    first_auth_transaction
    second_auth_transaction

    success('ok') # returns Dry::Monads::Right('ok')
  end

  private

  def first_auth_transaction
    # do something...
  end

  def second_auth_transaction
    raise AuthError, 'Auth error message' if @options[:auth_error]
  end

  # Wrapper for your error result
  def error_wrap(error)
    error # 'User already authed' || 'Auth error message'
  end

  # Wrapper for your success results
  def success_wrap(success_result)
    success_result # ok
  end
end
success = Auth.call(email: 'email', password: 'password')
# Dry::Monads::Right('ok')

failure = Auth.call(email: 'email', password: 'password', failure: true)
# Dry::Monads::Left('User already authed')

raised_error = Auth.call(email: 'email', password: 'password', auth_error: true)
# Dry::Monads::Left('Auth error message')

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/operators-rb/operators-service.

License

The gem is available as open source under the terms of the MIT License.

You can’t perform that action at this time.