Sha256: 7e73094b2f12b64427c620426896b7c4e72db40bada827ff4ce83343a43acfac

Contents?: true

Size: 1.33 KB

Versions: 1

Compression:

Stored size: 1.33 KB

Contents

# frozen_string_literal: true

require "active_model/validations"
require "plissken"
require "tainbox"

class Polist::Service
  class Failure < StandardError
    attr_accessor :response

    def initialize(response)
      self.response = response
      super
    end
  end

  class Form
    include Tainbox
    include ActiveModel::Validations
  end

  attr_accessor :params

  def self.call(*args)
    build(*args).tap(&:call)
  end

  def self.run(*args)
    build(*args).tap(&:run)
  end

  def self.param(*names)
    names.each do |name|
      define_method(name) { params.fetch(name) }
    end
  end

  def initialize(params)
    self.params = params
  end

  def call; end # Should be implemented in subclasses

  def run
    call
  rescue Failure => error
    @response = error.response
    @failure = true
  end

  def response
    @response ||= {}
  end

  def failure?
    !!@failure
  end

  def success?
    !failure?
  end

  def validate!
    error!(form.errors.to_h.values.first) unless form.valid?
  end

  private

  def form
    @form ||= self.class::Form.new(form_attributes.to_snake_keys)
  end

  def form_attributes
    params
  end

  def fail!(response = {})
    raise self.class::Failure.new(response)
  end

  def error!(message = "")
    fail!(error: message)
  end

  def success!(response = {})
    @response = response
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
polist-0.1.0 lib/polist/service.rb