-
Notifications
You must be signed in to change notification settings - Fork 88
/
validators.cr
67 lines (56 loc) · 1.86 KB
/
validators.cr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
require "./error"
# Analyze validation blocks and procs
#
# By example:
# ```
# validate :name, "can't be blank" do |user|
# !user.name.to_s.blank?
# end
#
# validate :name, "can't be blank", ->(user : User) do
# !user.name.to_s.blank?
# end
#
# name_required = ->(model : Granite::Base) { !model.name.to_s.blank? }
# validate :name, "can't be blank", name_required
# ```
module Granite::Validators
@[JSON::Field(ignore: true)]
@[YAML::Field(ignore: true)]
# Returns all errors on the model.
getter errors = [] of Error
macro included
macro inherited
@@validators = Array({field: String, message: String, block: Proc(self, Bool)}).new
disable_granite_docs? def self.validate(message : String, &block : self -> Bool)
self.validate(:base, message, block)
end
disable_granite_docs? def self.validate(field : (Symbol | String), message : String, &block : self -> Bool)
self.validate(field, message, block)
end
disable_granite_docs? def self.validate(message : String, block : self -> Bool)
self.validate(:base, message, block)
end
disable_granite_docs? def self.validate(field : (Symbol | String), message : String, block : self -> Bool)
@@validators << {field: field.to_s, message: message, block: block}
end
end
end
# Runs all of `self`'s validators, returning `true` if they all pass, and `false`
# otherwise.
#
# If the validation fails, `#errors` will contain all the errors responsible for
# the failing.
def valid?
# Return false if any `ConversionError` were added
# when setting model properties
return false if errors.any? ConversionError
errors.clear
@@validators.each do |validator|
unless validator[:block].call(self)
errors << Error.new(validator[:field], validator[:message])
end
end
errors.empty?
end
end