class Services::Base

Public Class Methods

inherited(subclass) click to toggle source
# File lib/services/base.rb, line 11
def inherited(subclass)
  subclass.const_set :Error, Class.new(StandardError)
  subclass.public_send :include, Rails.application.routes.url_helpers if defined?(Rails)
  begin
    subclass.public_send :include, Asyncable
  rescue Services::NoBackgroundProcessorFound
  end
  subclass.public_send :prepend, CallLogger, ExceptionWrapper, UniquenessChecker
end
new() click to toggle source
# File lib/services/base.rb, line 24
def initialize
  @id = SecureRandom.hex(6)
end

Public Instance Methods

call(*args, **kwargs) click to toggle source
# File lib/services/base.rb, line 28
def call(*args, **kwargs)
  raise NotImplementedError
end

Private Instance Methods

_split_ids_and_objects(ids_or_objects, klass) click to toggle source
# File lib/services/base.rb, line 38
def _split_ids_and_objects(ids_or_objects, klass)
  ids_or_objects = Array(ids_or_objects)
  ids, objects = ids_or_objects.grep(Integer), ids_or_objects.grep(klass)
  if ids.size + objects.size < ids_or_objects.size
    raise "All params must be either #{klass.to_s.pluralize} or Integers: #{ids_or_objects.map { |id_or_object| [id_or_object.class, id_or_object.inspect].join(' - ')}}"
  end
  [ids, objects]
end
find_ids(ids_or_objects, klass = object_class) click to toggle source
# File lib/services/base.rb, line 47
def find_ids(ids_or_objects, klass = object_class)
  ids, objects = _split_ids_and_objects(ids_or_objects, klass)
  ids.concat objects.map(&:id) if objects.any?
  ids
end
find_objects(ids_or_objects, klass = object_class) click to toggle source
# File lib/services/base.rb, line 63
def find_objects(ids_or_objects, klass = object_class)
  ids, objects = _split_ids_and_objects(ids_or_objects, klass)
  if ids.any?
    objects_from_ids = find_service(klass).call(ids)
    object_ids = if objects_from_ids.is_a?(ActiveRecord::Relation)
      objects_from_ids.pluck(:id)
    else
      objects_from_ids.map(&:id)
    end
    missing_ids = ids - object_ids
    raise self.class::Error, "#{klass.to_s.pluralize(missing_ids)} #{missing_ids.join(', ')} not found." if missing_ids.size > 0
    objects.concat objects_from_ids
  end
  objects
end
find_service(klass) click to toggle source
# File lib/services/base.rb, line 53
def find_service(klass)
  find_service_name = "#{klass.to_s.pluralize}::Find"
  candidates = ["Services::#{find_service_name}", find_service_name]
  # Use a lazy enumerator here because attempting to
  # constantize the find service without a namespace
  # might raise a circular dependency error if it has
  # a namespace
  candidates.lazy.map(&:safe_constantize).detect(&:itself) or raise self.class::Error, "Could not find find service (tried: #{candidates.join(', ')})"
end
log(message, meta = {}, severity = 'info') click to toggle source
# File lib/services/base.rb, line 34
def log(message, meta = {}, severity = 'info')
  Services.configuration.logger.log message, meta.merge(service: self.class.to_s, id: @id), severity
end