Class: Dry::Validation::Rule

Inherits:
Function show all
Defined in:
lib/dry/validation/rule.rb

Overview

Rules capture configuration and evaluator blocks

When a rule is applied, it creates an Evaluator using schema result and its block will be evaluated in the context of the evaluator.

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#keysArray<Symbol, String, 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<Symbol, String, Hash>)


21
# File 'lib/dry/validation/rule.rb', line 21

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>)


26
# File 'lib/dry/validation/rule.rb', line 26

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

Instance Method Details

#add_macro_from_hash(macros, spec) ⇒ Object



128
129
130
131
132
# File 'lib/dry/validation/rule.rb', line 128

def add_macro_from_hash(macros, spec)
  spec.each do |k, v|
    macros << [k, v.is_a?(Array) ? v : [v]]
  end
end

#call(contract, result) ⇒ 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.

Evaluate the rule within the provided context

Parameters:



34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/dry/validation/rule.rb', line 34

def call(contract, result)
  Evaluator.new(
    contract,
    keys: keys,
    macros: macros,
    block_options: block_options,
    result: result,
    values: result.values,
    _context: result.context,
    &block
  )
end

#each(*macros, &block) ⇒ Rule

Define a validation function for each element of an array

The function will be applied only if schema checks passed for a given array item.

rubocop:disable Metrics/AbcSize

Examples:

rule(:nums).each do |index:|
  key([:number, index]).failure("must be greater than 0") if value < 0
end
rule(:nums).each(min: 3)
rule(address: :city) do
   key.failure("oops") if value != 'Munich'
end

Returns:



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/dry/validation/rule.rb', line 78

def each(*macros, &block)
  root = keys[0]
  macros = parse_macros(*macros)
  @keys = []

  @block = proc do
    unless result.base_error?(root) || !values.key?(root) || values[root].nil?
      values[root].each_with_index do |_, idx|
        path = [*Schema::Path[root].to_a, idx]

        next if result.schema_error?(path)

        evaluator = with(macros: macros, keys: [path], index: idx, &block)

        failures.concat(evaluator.failures)
      end
    end
  end

  @block_options = map_keywords(block) if block

  self
end

#inspectString

Return a nice string representation

Returns:

  • (String)


108
109
110
# File 'lib/dry/validation/rule.rb', line 108

def inspect
  %(#<#{self.class} keys=#{keys.inspect}>)
end

#parse_macros(*args) ⇒ Array

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.

Parse function arguments into macros structure

Returns:

  • (Array)


117
118
119
120
121
122
123
124
125
126
# File 'lib/dry/validation/rule.rb', line 117

def parse_macros(*args)
  args.each_with_object([]) do |spec, macros|
    case spec
    when Hash
      add_macro_from_hash(macros, spec)
    else
      macros << Array(spec)
    end
  end
end

#validate(*macros, &block) ⇒ Rule

Define which macros should be executed

Returns:

See Also:



53
54
55
56
57
# File 'lib/dry/validation/rule.rb', line 53

def validate(*macros, &block)
  @macros = parse_macros(*macros)
  @block = block if block
  self
end