Ruby service classes with enforced1 input, output and error data structure definition.
Add this line to your application's Gemfile:
gem 'teckel'And then execute:
$ bundle
Or install it yourself as:
$ gem install teckel
Working with Interactor, Trailblazer's Operation and Dry-rb's Transaction and probably a hand full of inconsistent "service objects", I missed a system that:
- provides and enforces well defined input, output and error structures
 - makes chaining multiple operation easy and reliable
 - is easy to debug
 
For a full overview please see the Docs:
class CreateUser
  include Teckel::Operation
  # DSL style declaration
  input Struct.new(:name, :age, keyword_init: true)
  # Constant style declaration
  Output = ::User
  # Well, also Constant style, but using classic `class` notation
  class Error
    def initialize(message:, status_code:, meta:)
      @message, @status_code, @meta = message, status_code, meta
    end
    attr_reader :message, :status_code, :meta
  end
  error_constructor :new
  def call(input)
    user = User.new(name: input.name, age: input.age)
    if user.save
      success!(user)
    else
      fail!(
        message: "Could not create User",
        status_code: 400,
        meta: { validation: user.errors }
      )
    end
  end
end
CreateUser.call(name: "Bob", age: 23) #=> #<User @age=23, @name="Bob">
CreateUser.call(name: "Bob", age: 5)  #=> #<CreateUser::Error @message="Could not create User", @meta={:validation=>[{:age=>"underage"}]}, @status_code=400>After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.
Bug reports and pull requests are welcome on GitHub at https://github.com/fnordfish/teckel. Feature requests should provide a detailed explanation of the missing or changed behavior, if possible including some sample code.
Please also see DEVELOPMENT.md for planned features and general guidelines.