Class: Dry::Validation::Evaluator

Inherits:
Object
  • Object
show all
Extended by:
Initializer
Defined in:
lib/dry/validation/evaluator.rb

Overview

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(contract, **options, &block) ⇒ Evaluator

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Initialize a new evaluator


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# 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

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args, &block) ⇒ Object (private)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Forward to the underlying contract


222
223
224
225
226
227
228
229
# 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

Instance Attribute Details

#_contextConcurrent::Map (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Concurrent::Map)

47
# File 'lib/dry/validation/evaluator.rb', line 47

option :_context

#_contractContract (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:


27
# File 'lib/dry/validation/evaluator.rb', line 27

param :_contract

#_optionsHash (readonly)

Returns:

  • (Hash)

65
66
67
# File 'lib/dry/validation/evaluator.rb', line 65

def _options
  @_options
end

#block_optionsHash<Symbol=>Symbol> (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Hash<Symbol=>Symbol>)

62
# File 'lib/dry/validation/evaluator.rb', line 62

option :block_options, default: proc { EMPTY_HASH }

#keysArray<String, Symbol, Hash> (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Array<String, Symbol, Hash>)

37
# File 'lib/dry/validation/evaluator.rb', line 37

option :keys

#macrosArray<Symbol> (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Array<Symbol>)

42
# File 'lib/dry/validation/evaluator.rb', line 42

option :macros, optional: true, default: proc { EMPTY_ARRAY.dup }

#pathDry::Schema::Path (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:


52
# File 'lib/dry/validation/evaluator.rb', line 52

option :path, default: proc { Dry::Schema::Path[(key = keys.first) ? key : ROOT_PATH] }

#resultResult (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:


32
# File 'lib/dry/validation/evaluator.rb', line 32

option :result

#valuesObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Object)

57
# File 'lib/dry/validation/evaluator.rb', line 57

option :values

Instance Method Details

#baseFailures

Get `Failures` object for base errors

Returns:

See Also:


106
107
108
# File 'lib/dry/validation/evaluator.rb', line 106

def base
  @base ||= Failures.new
end

#base_rule_error?Boolean

Check if there are any base rule errors

Returns:

  • (Boolean)

208
209
210
# File 'lib/dry/validation/evaluator.rb', line 208

def base_rule_error?
  !base.empty? || result.base_rule_error?
end

#failuresArray<Hash>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return aggregated failures

Returns:

  • (Array<Hash>)

115
116
117
118
119
120
# 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) ⇒ Failures

Get `Failures` object for the default or provided path

Parameters:

  • path (Symbol, String, Hash, Array<Symbol>) (defaults to: self.path)

Returns:

See Also:


95
96
97
# 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) ⇒ Boolean

Return if the value under the default key is available

This is useful when dealing with rules for optional keys

Examples:

use the default key name

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

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

Returns:

  • (Boolean)

173
174
175
# File 'lib/dry/validation/evaluator.rb', line 173

def key?(name = key_name)
  values.key?(name)
end

#key_nameSymbol

Return default (first) key name

Returns:

  • (Symbol)

132
133
134
# File 'lib/dry/validation/evaluator.rb', line 132

def key_name
  @key_name ||= keys.first
end

#respond_to_missing?(meth, include_private = false) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)

213
214
215
# 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) ⇒ Boolean

Check if there are any errors on the current rule

Parameters:

  • path (Symbol, String, Array) (defaults to: nil)

    A Path-compatible spec

Returns:

  • (Boolean)

195
196
197
198
199
200
201
# 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) ⇒ Boolean

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

Parameters:

  • path (Symbol, String, Array)

    A Path-compatible spec

Returns:

  • (Boolean)

184
185
186
# File 'lib/dry/validation/evaluator.rb', line 184

def schema_error?(path)
  result.schema_error?(path)
end

#valueObject

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

Examples:

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

Returns:

  • (Object)

150
151
152
# File 'lib/dry/validation/evaluator.rb', line 150

def value
  values[key_name]
end

#with(new_opts, &block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


123
124
125
# File 'lib/dry/validation/evaluator.rb', line 123

def with(new_opts, &block)
  self.class.new(_contract, **_options, **new_opts, &block)
end