module Teckel::Operation
The main operation Mixin
Each operation is expected to declare input
. output
and error
classes.
There are two ways of declaring those classes. The first way is to define the constants Input
, Output
and Error
, the second way is to use the input
. output
and error
methods to point them to anonymous classes.
If you like “traditional” result objects to ask successful?
or failure?
on, use {Teckel::Operation::Config#result! result!} and get {Teckel::Operation::Result}
By default, input
. output
and error
classes are build using :[]
(eg: +Input[some: :param]+).
Use {Teckel::Operation::Config#input_constructor input_constructor}, {Teckel::Operation::Config#output_constructor output_constructor} and {Teckel::Operation::Config#error_constructor error_constructor} to change them.
@example class definitions via methods
class CreateUserViaMethods include Teckel::Operation input Types::Hash.schema(name: Types::String, age: Types::Coercible::Integer) output Types.Instance(User) error Types::Hash.schema(message: Types::String, errors: Types::Array.of(Types::Hash)) # @param [Hash<name: String, age: Integer>] # @return [User,Hash<message: String, errors: [Hash]>] def call(input) user = User.new(name: input[:name], age: input[:age]) if user.save success!(user) # exits early with success, prevents any further execution else fail!(message: "Could not save User", errors: user.errors) end end end # A success call: CreateUserViaMethods.call(name: "Bob", age: 23).is_a?(User) #=> true # A failure call: CreateUserViaMethods.call(name: "Bob", age: 10).eql?(message: "Could not save User", errors: [{age: "underage"}]) #=> true # Build your Input, Output and Error classes in a way that let you know: begin; CreateUserViaMethods.call(unwanted: "input"); rescue => e; e end.is_a?(::Dry::Types::MissingKeyError) #=> true # Feed an instance of the input class directly to call: CreateUserViaMethods.call(CreateUserViaMethods.input[name: "Bob", age: 23]).is_a?(User) #=> true
@!visibility public
Public Class Methods
# File lib/teckel/operation.rb, line 189 def self.included(receiver) receiver.extend Config receiver.extend ClassMethods receiver.send :include, InstanceMethods end