Class: DeeplyValid::Validation

Inherits:
Object
  • Object
show all
Defined in:
lib/deeply_valid/validation.rb

Overview

The Validation lets us define validations using several different kinds of rules.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(rule = nil, options = {}, &block) ⇒ Validation

The initializer defines the conditions that will satasfy this validation.

Parameters:

  • rule (Regexp) (defaults to: nil)

    When ‘rule` is a `Regexp` we use `=~` to validate

  • rule (Hash) (defaults to: nil)

    When ‘rule` is a `Hash`, then `valid_structure?` does the validation

  • rule (Object) (defaults to: nil)

    When ‘rule` is any other non-nil object, use `==` to validate

  • &block (Proc)

    An optional block, which will take one param and return true or false



20
21
22
23
24
25
26
27
28
29
# File 'lib/deeply_valid/validation.rb', line 20

def initialize(rule = nil, options = {}, &block)

  if rule.nil? && !block_given?
    raise "No validation rule specified"
  end

  @options = options
  @rule = rule
  @block = block
end

Instance Attribute Details

#optionsObject

Returns the value of attribute options.



9
10
11
# File 'lib/deeply_valid/validation.rb', line 9

def options
  @options
end

Instance Method Details

#valid?(data) ⇒ Boolean

Validate data of any rule type.

Parameters:

  • data (Object)

    the data to be validated

Returns:

  • (Boolean)

    true if valid, false if invalid



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/deeply_valid/validation.rb', line 90

def valid?(data)

  @data = data

  rule = @rule.is_a?(Proc) ? @rule.call(@data) : @rule

  result = if rule.kind_of?(Regexp)
    valid_pattern?(data)

  elsif rule.kind_of?(Validation)
    rule.valid?(data)

  elsif rule.kind_of?(Hash)
    valid_structure?(data)

  elsif @block
    @block.call(data)

  else
    data == @rule
  end

  @data = nil

  result

end

#valid_pattern?(data) ⇒ Boolean

Validate data by regexp

Parameters:

  • String (String)

    to be validated

Returns:

  • (Boolean)


36
37
38
# File 'lib/deeply_valid/validation.rb', line 36

def valid_pattern?(data)
  !!(data =~ @rule)
end

#valid_structure?(data, fragment_rule = nil) ⇒ Boolean

Recursively validate a complex data structure For now, only hashes are supported.

Example Rules:

{ :key => /regexp/ }
{ :key => Validation.new { |d| d > 20 } }
{ :key => "literal" }
{ :key => { :key2 => /regexp/ }, :key2 => "literal" }

As you see, rules can be nested arbitrarily deep. The validaions work like you would expect.

{ :key => /[a-z]+/ } will validate { :key => "a" } 
{ :key => /[a-z]+/ } will NOT validate { :key => 123 }

Parameters:

  • Hash (Hash)

    fragment to be validated

  • Optional (Hash)

    rules for validating hash fragment

Returns:

  • (Boolean)

    true if valid, false if invalid



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/deeply_valid/validation.rb', line 61

def valid_structure?(data, fragment_rule = nil)
  (fragment_rule || @rule).all? do |k, v|

    v = v.call(@data) if v.is_a?(Proc)

    if v.is_a?(Validation)
      (v.options[:optional] && !data.has_key?(k)) || v.valid?(data[k])

    elsif v.is_a?(Regexp)
      !!(data[k] =~ v)

    elsif v.is_a?(Hash)
      valid_structure?(data[k], v)

    elsif v.nil?
      !data.has_key?(k)

    else
      data[k] == v
    end
  end
end