Module: Dry::Transaction::Extra::Steps::Maybe::DSL

Defined in:
lib/dry/transaction/extra/steps/maybe.rb

Defined Under Namespace

Classes: NoValidatorError

Instance Method Summary collapse

Instance Method Details

#maybe(txn_or_container, key = nil, as: nil) ⇒ Object

Just like the ‘use` step, this invokes another transaction. However, it first checks to see if the transaction implements a `validator` method (usually provided by the validation_dsl extension), and if so, will call it before invoking the transaction.

If the validation succeeds, then it invokes the transaction as normal. If it fails, it continues on with the next step, passing the original input through.

step :create_user maybe VerifyEmail



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/dry/transaction/extra/steps/maybe.rb', line 30

def maybe(txn_or_container, key = nil, as: nil)
  if key
    container = txn_or_container
    method_name = as || "#{container.name}.#{key}".to_sym
  else
    txn = txn_or_container
    method_name = as || txn.name.to_sym
  end

  merge(method_name, as:)
  define_method method_name do |*args|
    txn = container[key] if key
    raise NoValidatorError, txn unless txn.respond_to? :validator

    result = txn.validator.new.call(*args)
    if result.failure?
      # Rails.logger.debug "Skipping #{txn} because of errors: #{result.errors.to_h}"
      return Success(*args)
    end

    txn.call(*args)
  end
rescue NoMethodError => e
  raise e unless e.name == :name

  raise ArgumentError, "unable to determine step name from #{key_or_container}.\
      Pass an explicit step name using `as:` keyword argument."
end