Module: Operations::Convenience

Defined in:
lib/operations/convenience.rb

Overview

This module helps to follow conventions. Work best with Operations::Command.build

Unders the hood it defines classes in accordance to the nesting convenience. It is always possible to use this module along with the manually crafted components if necessary.

Also, if this class is used as a container to cache the command instance under some name, this module will provide a method missing to call the command with ‘#call!` method using the `#call` method as an interface.

This is especially convenient when you have a DSL that expects some object responding to ‘#call` method but you want to raise an exception. In this case you would just pass `Namespace::OperationName.default!` into it.

Examples:


class Namespace::OperationName
  extend Operations::Convenience

  contract do
    params { ... }
    rule(...) { ... }
  end

  policy do |current_user, **|
    current_user.is_a?(Superuser) && ...
  end

  def call(context_value1, context_value2, **params)
    ...
  end
end

class Namespace::OperationName
  extend Operations::Convenience

  def self.default
    Operations::Command.new(...)
  end
end

# A normall command call
Namespace::OperationName.default.call(...)
# Raises exception in case of failure
Namespace::OperationName.default.call!(...)
# Acts exactly the same way as the previous one
# but notice where the bang is.
Namespace::OperationName.default!.call(...)

See Also:

Class Method Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, **kwargs, &block) ⇒ Object



66
67
68
69
70
71
72
73
# File 'lib/operations/convenience.rb', line 66

def method_missing(name, *args, **kwargs, &block)
  name_without_suffix = name.to_s.delete_suffix("!").to_sym
  if name.to_s.end_with?("!") && respond_to?(name_without_suffix)
    public_send(name_without_suffix, *args, **kwargs, &block).method(:call!)
  else
    super
  end
end

Class Method Details

.extended(mod) ⇒ Object



60
61
62
63
64
# File 'lib/operations/convenience.rb', line 60

def self.extended(mod)
  mod.include Dry::Monads[:result]
  mod.include Dry::Monads::Do.for(:call)
  mod.extend Dry::Initializer
end

Instance Method Details

#contract(prefix = nil, from: OperationContract, &block) ⇒ Object



79
80
81
82
83
84
# File 'lib/operations/convenience.rb', line 79

def contract(prefix = nil, from: OperationContract, &block)
  contract = Class.new(from)
  contract.config.messages.namespace = name.underscore
  contract.class_eval(&block)
  const_set(:"#{prefix.to_s.camelize}Contract", contract)
end

#respond_to_missing?(name) ⇒ Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/operations/convenience.rb', line 75

def respond_to_missing?(name, *)
  (name.to_s.end_with?("!") && respond_to?(name.to_s.delete_suffix("!").to_sym)) || super
end