class Dry::Validation::Evaluator

Evaluator is the execution context for rules

Evaluators expose an API for setting failure messages and forward method calls to the contracts, so that you can use your contract methods within rule blocks

@api public

Attributes

_options[R]

@return [Hash]

Public Class Methods

new(contract, **options, &block) click to toggle source

Initialize a new evaluator

@api private

Calls superclass method
# File lib/dry/validation/evaluator.rb, line 70
def initialize(contract, **options, &block)
  super(contract, **options)

  @_options = options

  if block
    exec_opts = block_options.transform_values { _options[_1] }
    instance_exec(**exec_opts, &block)
  end

  macros.each do |args|
    macro = macro(*args.flatten(1))
    instance_exec(**macro.extract_block_options(_options.merge(macro: macro)), &macro.block)
  end
end

Public Instance Methods

base() click to toggle source

Get `Failures` object for base errors

@return [Failures]

@see Failures#failure

@api public

# File lib/dry/validation/evaluator.rb, line 106
def base
  @base ||= Failures.new
end
base_rule_error?() click to toggle source

Check if there are any base rule errors

@return [Boolean]

@api public

# File lib/dry/validation/evaluator.rb, line 208
def base_rule_error?
  !base.empty? || result.base_rule_error?
end
failures() click to toggle source

Return aggregated failures

@return [Array<Hash>]

@api private

# File lib/dry/validation/evaluator.rb, line 115
def failures
  @failures ||= []
  @failures += @base.opts if defined?(@base)
  @failures.concat(@key.values.flat_map(&:opts)) if defined?(@key)
  @failures
end
key(path = self.path) click to toggle source

Get `Failures` object for the default or provided path

@param [Symbol,String,Hash,Array<Symbol>] path

@return [Failures]

@see Failures#failure

@api public

# File lib/dry/validation/evaluator.rb, line 95
def key(path = self.path)
  (@key ||= EMPTY_HASH.dup)[path] ||= Failures.new(path)
end
key?(name = key_name) click to toggle source

Return if the value under the default key is available

This is useful when dealing with rules for optional keys

@example use the default key name

rule(:age) do
  key.failure(:invalid) if key? && value < 18
end

@example specify the key name

rule(:start_date, :end_date) do
  if key?(:start_date) && !key?(:end_date)
    key(:end_date).failure("must provide an end_date with start_date")
  end
end

@return [Boolean]

@api public

# File lib/dry/validation/evaluator.rb, line 173
def key?(name = key_name)
  values.key?(name)
end
key_name() click to toggle source

Return default (first) key name

@return [Symbol]

@api public

# File lib/dry/validation/evaluator.rb, line 132
def key_name
  @key_name ||= keys.first
end
respond_to_missing?(meth, include_private = false) click to toggle source

@api private

Calls superclass method
# File lib/dry/validation/evaluator.rb, line 213
def respond_to_missing?(meth, include_private = false)
  super || _contract.respond_to?(meth, true)
end
rule_error?(path = nil) click to toggle source

Check if there are any errors on the current rule

@param path [Symbol, String, Array] A Path-compatible spec

@return [Boolean]

@api public

# File lib/dry/validation/evaluator.rb, line 195
def rule_error?(path = nil)
  if path.nil?
    !key(self.path).empty?
  else
    result.rule_error?(path)
  end
end
schema_error?(path) click to toggle source

Check if there are any errors on the schema under the provided path

@param path [Symbol, String, Array] A Path-compatible spec

@return [Boolean]

@api public

# File lib/dry/validation/evaluator.rb, line 184
def schema_error?(path)
  result.schema_error?(path)
end
value() click to toggle source

Return the value found under the first specified key

This is a convenient method that can be used in all the common cases where a rule depends on just one key and you want a quick access to the value

@example

rule(:age) do
  key.failure(:invalid) if value < 18
end

@return [Object]

@api public

# File lib/dry/validation/evaluator.rb, line 150
def value
  values[key_name]
end
with(new_opts, &block) click to toggle source

@api private

# File lib/dry/validation/evaluator.rb, line 123
def with(new_opts, &block)
  self.class.new(_contract, **_options, **new_opts, &block)
end

Private Instance Methods

method_missing(meth, *args, &block) click to toggle source

Forward to the underlying contract

@api private

Calls superclass method
# File lib/dry/validation/evaluator.rb, line 222
def method_missing(meth, *args, &block)
  # yes, we do want to delegate to private methods too
  if _contract.respond_to?(meth, true)
    _contract.__send__(meth, *args, &block)
  else
    super
  end
end