Class: Tina4::Validator
- Inherits:
-
Object
- Object
- Tina4::Validator
- Defined in:
- lib/tina4/validator.rb
Overview
Request body validator with chainable rules.
Usage:
validator = Tina4::Validator.new(request.body)
validator.required("name", "email")
.email("email")
.min_length("name", 2)
.max_length("name", 100)
.integer("age")
.min("age", 0)
.max("age", 150)
.in_list("role", ["admin", "user", "guest"])
.regex("phone", /^\+?[\d\s\-]+$/)
unless validator.is_valid?
return response.error("VALIDATION_FAILED", validator.errors.first[:message], 400)
end
Constant Summary collapse
- EMAIL_REGEX =
/\A[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}\z/
Instance Attribute Summary collapse
-
#validation_errors ⇒ Object
readonly
Returns the value of attribute validation_errors.
Instance Method Summary collapse
-
#email(field) ⇒ Object
Check that a field contains a valid email address.
-
#errors ⇒ Object
Return the list of validation errors (empty if valid).
-
#in_list(field, allowed) ⇒ Object
Check that a field's value is one of the allowed values.
-
#initialize(data = {}) ⇒ Validator
constructor
A new instance of Validator.
-
#integer(field) ⇒ Object
Check that a field is an integer (or can be parsed as one).
-
#is_valid? ⇒ Boolean
(also: #valid?)
Return true if no validation errors have been recorded.
-
#max(field, maximum) ⇒ Object
Check that a numeric field is <=
maximum. -
#max_length(field, length) ⇒ Object
Check that a string field has at most
lengthcharacters. -
#min(field, minimum) ⇒ Object
Check that a numeric field is >=
minimum. -
#min_length(field, length) ⇒ Object
Check that a string field has at least
lengthcharacters. -
#regex(field, pattern) ⇒ Object
Check that a field matches a regular expression.
-
#required(*fields) ⇒ Object
Check that one or more fields are present and non-empty.
Constructor Details
#initialize(data = {}) ⇒ Validator
Returns a new instance of Validator.
29 30 31 32 33 34 |
# File 'lib/tina4/validator.rb', line 29 def initialize(data = {}) @data = data.is_a?(Hash) ? data : {} # Normalise keys to strings for consistent lookup @data = @data.transform_keys(&:to_s) unless @data.empty? @validation_errors = [] end |
Instance Attribute Details
#validation_errors ⇒ Object (readonly)
Returns the value of attribute validation_errors.
25 26 27 |
# File 'lib/tina4/validator.rb', line 25 def validation_errors @validation_errors end |
Instance Method Details
#email(field) ⇒ Object
Check that a field contains a valid email address.
49 50 51 52 53 54 55 56 57 58 |
# File 'lib/tina4/validator.rb', line 49 def email(field) key = field.to_s value = @data[key] return self if value.nil? unless value.is_a?(String) && value.match?(EMAIL_REGEX) @validation_errors << { field: key, message: "#{key} must be a valid email address" } end self end |
#errors ⇒ Object
Return the list of validation errors (empty if valid).
168 169 170 |
# File 'lib/tina4/validator.rb', line 168 def errors @validation_errors.dup end |
#in_list(field, allowed) ⇒ Object
Check that a field's value is one of the allowed values.
139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/tina4/validator.rb', line 139 def in_list(field, allowed) key = field.to_s value = @data[key] return self if value.nil? unless allowed.include?(value) # Canonical wording (VALID-TWO-MESSAGES): render the allowed set as # compact JSON so every framework prints the SAME list -- Node # JSON.stringify, PHP json_encode, Python json.dumps and this to_json all # emit ["admin","user","guest"] (no spaces), never a language repr. @validation_errors << { field: key, message: "#{key} must be one of #{allowed.to_json}" } end self end |
#integer(field) ⇒ Object
Check that a field is an integer (or can be parsed as one).
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/tina4/validator.rb', line 85 def integer(field) key = field.to_s value = @data[key] return self if value.nil? if value.is_a?(Integer) return self end begin Integer(value) rescue ArgumentError, TypeError @validation_errors << { field: key, message: "#{key} must be an integer" } end self end |
#is_valid? ⇒ Boolean Also known as: valid?
Return true if no validation errors have been recorded.
173 174 175 |
# File 'lib/tina4/validator.rb', line 173 def is_valid? @validation_errors.empty? end |
#max(field, maximum) ⇒ Object
Check that a numeric field is <= maximum.
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/tina4/validator.rb', line 121 def max(field, maximum) key = field.to_s value = @data[key] return self if value.nil? begin num = Float(value) rescue ArgumentError, TypeError return self end if num > maximum @validation_errors << { field: key, message: "#{key} must be at most #{maximum}" } end self end |
#max_length(field, length) ⇒ Object
Check that a string field has at most length characters.
73 74 75 76 77 78 79 80 81 82 |
# File 'lib/tina4/validator.rb', line 73 def max_length(field, length) key = field.to_s value = @data[key] return self if value.nil? unless value.is_a?(String) && value.length <= length @validation_errors << { field: key, message: "#{key} must be at most #{length} characters" } end self end |
#min(field, minimum) ⇒ Object
Check that a numeric field is >= minimum.
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/tina4/validator.rb', line 103 def min(field, minimum) key = field.to_s value = @data[key] return self if value.nil? begin num = Float(value) rescue ArgumentError, TypeError return self end if num < minimum @validation_errors << { field: key, message: "#{key} must be at least #{minimum}" } end self end |
#min_length(field, length) ⇒ Object
Check that a string field has at least length characters.
61 62 63 64 65 66 67 68 69 70 |
# File 'lib/tina4/validator.rb', line 61 def min_length(field, length) key = field.to_s value = @data[key] return self if value.nil? unless value.is_a?(String) && value.length >= length @validation_errors << { field: key, message: "#{key} must be at least #{length} characters" } end self end |
#regex(field, pattern) ⇒ Object
Check that a field matches a regular expression.
155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/tina4/validator.rb', line 155 def regex(field, pattern) key = field.to_s value = @data[key] return self if value.nil? regexp = pattern.is_a?(Regexp) ? pattern : Regexp.new(pattern) unless value.is_a?(String) && value.match?(regexp) @validation_errors << { field: key, message: "#{key} does not match the required format" } end self end |
#required(*fields) ⇒ Object
Check that one or more fields are present and non-empty.
37 38 39 40 41 42 43 44 45 46 |
# File 'lib/tina4/validator.rb', line 37 def required(*fields) fields.each do |field| key = field.to_s value = @data[key] if value.nil? || (value.is_a?(String) && value.strip.empty?) @validation_errors << { field: key, message: "#{key} is required" } end end self end |