29
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
# File 'lib/errapi/object_validator.rb', line 29
def validate value, context, options = {}
return context.valid? unless @validations
location = if options[:location]
options[:location]
elsif options[:location_type]
builder = "#{options[:location_type]}_location"
raise "Unknown location type #{options[:location_type].inspect}" unless respond_to? builder
send builder
else
no_location
end
source = options[:source]
context_proxy = ContextProxy.new context, self, location
@validations.each do |validation_definition|
each = validation_definition[:each]
each_values = nil
each_values_set = nil
if each
each_values = (value, each[:target], options)[:value]
each_values_set = each_values.collect{ |v| true } if each_values.kind_of? Array
each_values = [] unless each_values.kind_of? Array
each_sources = each_values.collect{ |v| source }
else
each_values = [ value ]
each_values_set = [ options.fetch(:value_set, true) ]
each_sources = [ source ]
end
each_location = each ? location.relative(each[:options][:as] || each[:target]) : location
each_values.each.with_index do |each_value,i|
each_index_location = each ? each_location.relative(i) : location
context_proxy.current_location = each_index_location
next if validation_definition[:conditions].any?{ |condition| !condition.fulfilled?(each_value, context_proxy) }
validation_definition[:validations].each do |validation|
next if validation[:conditions] && validation[:conditions].any?{ |condition| !condition.fulfilled?(each_value, context_proxy) }
validation_definition[:targets].each do |target|
target_value_info = each_value, target, value_set: each_values_set[i], source: source
validation_location = target ? each_index_location.relative(validation[:target_alias] || target) : each_index_location
context_proxy.current_location = validation_location
error_options = {
value: target_value_info[:value],
source: target_value_info[:source],
value_set: target_value_info[:value_set],
constraints: validation[:validation_options]
}
error_options[:location] = validation_location unless validation_location.kind_of? Errapi::Locations::None
error_options[:validation] = validation[:validation_name] if validation[:validation_name]
context_proxy.with_error_options error_options do
validation_options = { location: validation_location, value_set: target_value_info[:value_set] }
validation[:validation].validate target_value_info[:value], context_proxy, validation_options
end
end
end
end
end
raise Errapi::ValidationFailed.new(context) if options[:raise_error] && context.errors?
context_proxy.valid?
end
|