Skip to content

Instantly share code, notes, and snippets.

@elskwid
Created February 11, 2016 00:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elskwid/557fd9ffd9e9e08d368c to your computer and use it in GitHub Desktop.
Save elskwid/557fd9ffd9e9e08d368c to your computer and use it in GitHub Desktop.
Base service object
require "concord"
require "procto"
# Small wrapper module for domain services.
#
# Creates a service object with a ::call method that delegates to the instance
# method name given in the `call` option. Defaults to :call. (Procto)
#
# Provides initializer arguments, sets the ivars, and optional public reader
# methods for the attribute names passed in for `attrs`. (Concord)
#
# Example:
#
# class CreateSomethingService
# include DomainService.new(:thing1, :thing2)
#
# def call
# # do stuff to thing1 and thing2
# end
# end
#
# CreateSomethingService.call(my_thing1, my_thing2)
#
# # or
#
# service = CreateSomethingService.new(my_thing1, my_thing2)
# service.my_thing1
# #=> my_thing1
# service.my_thing2
# #=> my_thing2
# service.call # same as the first ::call
#
# Inherits from Module to give us the include syntax
class DomainService < Module
# include DomainService.new(...)
# attrs - Attribute names for Concord
# call - Instance method to call from ::call
def initialize(*attrs, call: :call)
@attrs = attrs
@call = call
end
# Called when module is included.
def included(descendant)
# Provides ::call method that delegates to #call
descendant.send(:include, Procto.call(@call)) # rubocop:disable LambdaCall
# Provides #new and sets ivar + optional public reader
descendant.send(:include, Concord::Public.new(*@attrs))
# Define Failure error on module/class
descendant.const_set "Failure", failure_error_class
end
# General Failure from service, defined as a subclass of StandardError.
# An object can be passed in so the rescue block can inspect and use
# error data. For instance with AR Model errors.
def failure_error_class
Class.new(StandardError) do
include Concord::Public.new(:object)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment