Operators::Service
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.