active_validation 1.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +3 -1
- data/active_validation.gemspec +1 -0
- data/config/locales/en.yml +4 -0
- data/lib/active_validation/matchers/ensure_valid_alpha_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_alpha_numeric_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_base64_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_boolean_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_coordinate_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_credit_card_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_currency_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_cusip_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_email_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_equality_matcher_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_hex_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_imei_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_ip_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_isbn_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_isin_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_mac_address_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_name_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_password_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_phone_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_sedol_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_slug_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_ssn_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_tracking_number_format_of.rb +26 -0
- data/lib/active_validation/matchers/ensure_valid_url_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_username_format_of.rb +2 -2
- data/lib/active_validation/matchers/ensure_valid_uuid_format_of.rb +2 -2
- data/lib/active_validation/validators/alpha_numeric_validator.rb +10 -7
- data/lib/active_validation/validators/alpha_validator.rb +10 -8
- data/lib/active_validation/validators/base64_validator.rb +16 -1
- data/lib/active_validation/validators/coordinate_validator.rb +12 -3
- data/lib/active_validation/validators/credit_card_validator.rb +10 -10
- data/lib/active_validation/validators/currency_validator.rb +7 -6
- data/lib/active_validation/validators/cusip_validator.rb +11 -9
- data/lib/active_validation/validators/email_validator.rb +11 -7
- data/lib/active_validation/validators/equality_validator.rb +14 -7
- data/lib/active_validation/validators/hex_validator.rb +16 -1
- data/lib/active_validation/validators/imei_validator.rb +14 -12
- data/lib/active_validation/validators/ip_validator.rb +16 -1
- data/lib/active_validation/validators/isbn_validator.rb +8 -4
- data/lib/active_validation/validators/isin_validator.rb +16 -14
- data/lib/active_validation/validators/mac_address_validator.rb +21 -7
- data/lib/active_validation/validators/name_validator.rb +16 -1
- data/lib/active_validation/validators/password_validator.rb +7 -6
- data/lib/active_validation/validators/phone_validator.rb +16 -1
- data/lib/active_validation/validators/sedol_validator.rb +15 -10
- data/lib/active_validation/validators/slug_validator.rb +16 -1
- data/lib/active_validation/validators/ssn_validator.rb +16 -1
- data/lib/active_validation/validators/tracking_number_validator.rb +235 -0
- data/lib/active_validation/validators/url_validator.rb +11 -2
- data/lib/active_validation/validators/username_validator.rb +16 -1
- data/lib/active_validation/validators/uuid_validator.rb +11 -6
- data/lib/active_validation/version.rb +1 -1
- data/lib/active_validation.rb +5 -6
- metadata +18 -2
@@ -1,9 +1,24 @@
|
|
1
1
|
class Base64Validator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
unless value
|
4
|
+
unless valid?(value.to_s)
|
5
5
|
record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.base64'))
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
+
private
|
10
|
+
|
11
|
+
def valid_format?(value)
|
12
|
+
value =~ /^(?:[A-Za-z0-9+$]{4})*(?:[A-Za-z0-9+$]{2}==|[A-Za-z0-9+$]{3}=|[A-Za-z0-9+$]{4})$/
|
13
|
+
end
|
14
|
+
|
15
|
+
def valid_length?(value)
|
16
|
+
value.present?
|
17
|
+
end
|
18
|
+
|
19
|
+
def valid?(value)
|
20
|
+
valid_length?(value) &&
|
21
|
+
valid_format?(value)
|
22
|
+
end
|
23
|
+
|
9
24
|
end
|
@@ -7,7 +7,7 @@ class CoordinateValidator < ActiveModel::EachValidator
|
|
7
7
|
"Unknown boundary: #{boundary.inspect}. Valid boundaries are: #{BOUNDARIES.map(&:inspect).join(', ')}"
|
8
8
|
end
|
9
9
|
|
10
|
-
unless
|
10
|
+
unless valid?(value, options)
|
11
11
|
record.errors[attribute] << (options[:message] || I18n.t("active_validation.errors.messages.coordinate.#{boundary}"))
|
12
12
|
end
|
13
13
|
end
|
@@ -16,6 +16,10 @@ class CoordinateValidator < ActiveModel::EachValidator
|
|
16
16
|
|
17
17
|
BOUNDARIES = [:coordinate, :latitude, :longitude]
|
18
18
|
|
19
|
+
def valid_length?(value)
|
20
|
+
value.present?
|
21
|
+
end
|
22
|
+
|
19
23
|
def valid_latitude?(value)
|
20
24
|
value >= -90 && value <= 90
|
21
25
|
end
|
@@ -24,8 +28,8 @@ class CoordinateValidator < ActiveModel::EachValidator
|
|
24
28
|
value >= -180 && value <= 180
|
25
29
|
end
|
26
30
|
|
27
|
-
def valid_boundary?(value)
|
28
|
-
case options
|
31
|
+
def valid_boundary?(value, options)
|
32
|
+
case options.fetch(:boundary, :coordinate)
|
29
33
|
when :latitude
|
30
34
|
valid_latitude?(value)
|
31
35
|
when :longitude
|
@@ -35,4 +39,9 @@ class CoordinateValidator < ActiveModel::EachValidator
|
|
35
39
|
end
|
36
40
|
end
|
37
41
|
|
42
|
+
def valid?(value, options)
|
43
|
+
valid_length?(value) &&
|
44
|
+
valid_boundary?(value, options)
|
45
|
+
end
|
46
|
+
|
38
47
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class CreditCardValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
unless valid?(value, options)
|
4
|
+
unless valid?(value.to_s, options)
|
5
5
|
record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.credit_card'))
|
6
6
|
end
|
7
7
|
end
|
@@ -50,14 +50,12 @@ class CreditCardValidator < ActiveModel::EachValidator
|
|
50
50
|
}
|
51
51
|
|
52
52
|
def valid_format?(value, options)
|
53
|
-
|
54
|
-
value =~ /^[0-9]+$/
|
55
|
-
else
|
56
|
-
value =~ /^[0-9 -.]+$/
|
57
|
-
end
|
53
|
+
value =~ (options.fetch(:strict, false) ? /^[0-9]+$/ : /^[0-9 -.]+$/)
|
58
54
|
end
|
59
55
|
|
60
56
|
def valid_length?(value, options)
|
57
|
+
return(false) unless value.present?
|
58
|
+
|
61
59
|
value_size_range = DEFAULT_LENGTHS.values.flatten.uniq.sort
|
62
60
|
value_size = value.size
|
63
61
|
|
@@ -112,18 +110,20 @@ class CreditCardValidator < ActiveModel::EachValidator
|
|
112
110
|
when :visa
|
113
111
|
DEFAULT_PREFIXES[:visa].any? { |prefix| value.start_with?(prefix) }
|
114
112
|
else
|
115
|
-
|
113
|
+
result = false
|
116
114
|
DEFAULT_LENGTHS.each do |key, values|
|
117
115
|
if values.include?(value_size)
|
118
|
-
|
116
|
+
result = DEFAULT_PREFIXES[key].any? { |prefix| value.start_with?(prefix) }
|
117
|
+
break if result
|
119
118
|
end
|
119
|
+
break if result
|
120
120
|
end
|
121
|
-
|
121
|
+
return(result)
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
125
125
|
def valid?(value, options)
|
126
|
-
striped_value = value.
|
126
|
+
striped_value = value.gsub(/\D/, '')
|
127
127
|
|
128
128
|
valid_format?(value, options) &&
|
129
129
|
valid_length?(striped_value, options) &&
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class CurrencyValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
unless valid?(value, options)
|
4
|
+
unless valid?(value.to_s, options)
|
5
5
|
record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.currency'))
|
6
6
|
end
|
7
7
|
end
|
@@ -9,14 +9,15 @@ class CurrencyValidator < ActiveModel::EachValidator
|
|
9
9
|
private
|
10
10
|
|
11
11
|
def valid_format?(value, options)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
value =~ (options.fetch(:strict, false) ? /^\d+(\.\d{2})$/ : /^\d*+(\.\d{1,2})$/)
|
13
|
+
end
|
14
|
+
|
15
|
+
def valid_length?(value)
|
16
|
+
value.present?
|
17
17
|
end
|
18
18
|
|
19
19
|
def valid?(value, options)
|
20
|
+
valid_length?(value) &&
|
20
21
|
valid_format?(value, options)
|
21
22
|
end
|
22
23
|
|
@@ -8,24 +8,26 @@ class CusipValidator < ActiveModel::EachValidator
|
|
8
8
|
|
9
9
|
private
|
10
10
|
|
11
|
-
def valid_format?(value)
|
12
|
-
value =~ /^[0-9A-Z]{9}$/
|
13
|
-
end
|
14
|
-
|
15
11
|
def valid_checksum?(value)
|
16
|
-
digits = value.
|
12
|
+
digits = value.chars.map { |character| character.match(/[A-Z]/) ? (character.ord - 55) : character.to_i }
|
17
13
|
even_values = digits.values_at(* digits.each_index.select { |i| i.even? })
|
18
14
|
odd_values = digits.values_at(* digits.each_index.select { |i| i.odd? })
|
19
15
|
values = odd_values.map { |i| i * 2 }.zip(even_values).flatten
|
20
|
-
|
21
|
-
values = values.inject(0) do |sum, i|
|
22
|
-
sum += (i / 10) + i % 10
|
23
|
-
end
|
16
|
+
values = values.inject(0) { |sum, i| sum += (i / 10) + i % 10 }
|
24
17
|
|
25
18
|
((10 - values) % 10) % 10
|
26
19
|
end
|
27
20
|
|
21
|
+
def valid_format?(value)
|
22
|
+
value =~ /^[0-9A-Z]{9}$/
|
23
|
+
end
|
24
|
+
|
25
|
+
def valid_length?(value)
|
26
|
+
value.present?
|
27
|
+
end
|
28
|
+
|
28
29
|
def valid?(value)
|
30
|
+
valid_length?(value) &&
|
29
31
|
valid_format?(value) &&
|
30
32
|
valid_checksum?(value)
|
31
33
|
end
|
@@ -1,25 +1,29 @@
|
|
1
1
|
class EmailValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
unless valid?(value, options)
|
4
|
+
unless valid?(value.to_s, options)
|
5
5
|
record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.email'))
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
9
|
private
|
10
10
|
|
11
|
+
def valid_domain?(value, options)
|
12
|
+
options.empty? || options.any? { |domain| value.downcase.end_with?(".#{domain.downcase}") }
|
13
|
+
end
|
14
|
+
|
11
15
|
def valid_format?(value)
|
12
16
|
value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
|
13
17
|
end
|
14
18
|
|
15
|
-
def
|
16
|
-
|
17
|
-
options.empty? || options.any? { |domain| value_downcased.end_with?(".#{domain.downcase}") }
|
19
|
+
def valid_length?(value)
|
20
|
+
value.present?
|
18
21
|
end
|
19
22
|
|
20
|
-
def valid?(
|
21
|
-
|
22
|
-
|
23
|
+
def valid?(value, options)
|
24
|
+
valid_length?(value) &&
|
25
|
+
valid_format?(value) &&
|
26
|
+
valid_domain?(value, [*(options[:domain])])
|
23
27
|
end
|
24
28
|
|
25
29
|
end
|
@@ -1,15 +1,22 @@
|
|
1
1
|
class EqualityValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
4
|
+
to = options.fetch(:to, nil)
|
5
|
+
if to.nil?
|
6
|
+
raise ArgumentError,
|
7
|
+
"ArgumentError: missing ':to' attribute for comparison."
|
8
|
+
end
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
+
operator = options.fetch(:operator, nil)
|
11
|
+
operators = OPERATORS.keys
|
12
|
+
unless operators.include?(operator)
|
13
|
+
raise ArgumentError,
|
14
|
+
"Unknown operator: #{operator.inspect}. Valid operators are: #{operators.map(&:inspect).join(', ')}"
|
15
|
+
end
|
16
|
+
operator = OPERATORS.fetch(operator)
|
10
17
|
|
11
|
-
unless value.send(operator, record.send(
|
12
|
-
record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.equality', attr:
|
18
|
+
unless value.send(operator.to_sym, record.send(to.to_sym))
|
19
|
+
record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.equality', attr: to, operator: operator))
|
13
20
|
end
|
14
21
|
end
|
15
22
|
|
@@ -1,9 +1,24 @@
|
|
1
1
|
class HexValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
unless value
|
4
|
+
unless valid?(value.to_s)
|
5
5
|
record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.hex'))
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
+
private
|
10
|
+
|
11
|
+
def valid_format?(value)
|
12
|
+
value =~ /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/
|
13
|
+
end
|
14
|
+
|
15
|
+
def valid_length?(value)
|
16
|
+
value.present?
|
17
|
+
end
|
18
|
+
|
19
|
+
def valid?(value)
|
20
|
+
valid_length?(value) &&
|
21
|
+
valid_format?(value)
|
22
|
+
end
|
23
|
+
|
9
24
|
end
|
@@ -12,24 +12,26 @@ class ImeiValidator < ActiveModel::EachValidator
|
|
12
12
|
value =~ /\A[\d\.\:\-\s]+\z/i
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
|
17
|
-
|
18
|
-
sum, i = 0, 0
|
19
|
-
|
20
|
-
numbers.each_char do |ch|
|
21
|
-
n = ch.to_i
|
22
|
-
n *= 2 if i.odd?
|
23
|
-
n = 1 + (n - 10) if n >= 10
|
15
|
+
def valid_length?(value)
|
16
|
+
value.present?
|
17
|
+
end
|
24
18
|
|
25
|
-
|
26
|
-
|
19
|
+
def valid_luhn?(value)
|
20
|
+
number = value.gsub(/\D/, '').reverse
|
21
|
+
|
22
|
+
total = 0
|
23
|
+
number.chars.each_with_index do |character, i|
|
24
|
+
result = character.to_i
|
25
|
+
result *= 2 if i.odd?
|
26
|
+
result = (1 + (result - 10)) if (result >= 10)
|
27
|
+
total += result
|
27
28
|
end
|
28
29
|
|
29
|
-
(
|
30
|
+
(total % 10).zero?
|
30
31
|
end
|
31
32
|
|
32
33
|
def valid?(value)
|
34
|
+
valid_length?(value) &&
|
33
35
|
valid_format?(value) &&
|
34
36
|
valid_luhn?(value)
|
35
37
|
end
|
@@ -1,9 +1,24 @@
|
|
1
1
|
class IpValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
unless
|
4
|
+
unless valid?(value.to_s)
|
5
5
|
record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.ip'))
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
+
private
|
10
|
+
|
11
|
+
def valid_format?(value)
|
12
|
+
value =~ /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
|
13
|
+
end
|
14
|
+
|
15
|
+
def valid_length?(value)
|
16
|
+
value.present?
|
17
|
+
end
|
18
|
+
|
19
|
+
def valid?(value)
|
20
|
+
valid_length?(value) &&
|
21
|
+
valid_format?(value)
|
22
|
+
end
|
23
|
+
|
9
24
|
end
|
@@ -9,15 +9,19 @@ class IsbnValidator < ActiveModel::EachValidator
|
|
9
9
|
private
|
10
10
|
|
11
11
|
def valid_format?(value)
|
12
|
-
value = '' if value.
|
13
|
-
value.gsub
|
14
|
-
value.downcase!
|
12
|
+
value = '' if value.blank?
|
13
|
+
value = value.gsub(/-| /, '').downcase.chars
|
15
14
|
|
16
15
|
[10, 13].include?(value.size) &&
|
17
|
-
value.
|
16
|
+
value.all? { |character| ['0', '1', '2' , '3', '4', '5', '6', '7', '8', '9', '0', 'x'].include?(character) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def valid_length?(value)
|
20
|
+
value.present?
|
18
21
|
end
|
19
22
|
|
20
23
|
def valid?(value)
|
24
|
+
valid_length?(value) &&
|
21
25
|
valid_format?(value)
|
22
26
|
end
|
23
27
|
|
@@ -1,36 +1,38 @@
|
|
1
1
|
class IsinValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
unless valid?(value)
|
4
|
+
unless valid?(value.to_s)
|
5
5
|
record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.isin'))
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
9
|
private
|
10
10
|
|
11
|
-
def valid_format?(value)
|
12
|
-
value =~ /^((AF|AX|AL|DZ|AS|AD|AO|AI|AQ|AG|AR|AM|AW|AU|AT|AZ|BS|BH|BD|BB|BY|BE|BZ|BJ|BM|BT|BO|BQ|BA|BW|BV|BR|IO|BN|BG|BF|BI|KH|CM|CA|CV|KY|CF|TD|CL|CN|CX|CC|CO|KM|CG|CD|CK|CR|CI|HR|CU|CW|CY|CZ|DK|DJ|DM|DO|EC|EG|SV|GQ|ER|EE|ET|FK|FO|FJ|FI|FR|GF|PF|TF|GA|GM|GE|DE|GH|GI|GR|GL|GD|GP|GU|GT|GG|GN|GW|GY|HT|HM|VA|HN|HK|HU|IS|IN|ID|IR|IQ|IE|IM|IL|IT|JM|JP|JE|JO|KZ|KE|KI|KP|KR|KW|KG|LA|LV|LB|LS|LR|LY|LI|LT|LU|MO|MK|MG|MW|MY|MV|ML|MT|MH|MQ|MR|MU|YT|MX|FM|MD|MC|MN|ME|MS|MA|MZ|MM|NA|NR|NP|NL|NC|NZ|NI|NE|NG|NU|NF|MP|NO|OM|PK|PW|PS|PA|PG|PY|PE|PH|PN|PL|PT|PR|QA|RE|RO|RU|RW|BL|SH|KN|LC|MF|PM|VC|WS|SM|ST|SA|SN|RS|SC|SL|SG|SX|SK|SI|SB|SO|ZA|GS|SS|ES|LK|SD|SR|SJ|SZ|SE|CH|SY|TW|TJ|TZ|TH|TL|TG|TK|TO|TT|TN|TR|TM|TC|TV|UG|UA|AE|GB|US|UM|UY|UZ|VU|VE|VN|VG|VI|WF|EH|YE|ZM|ZW{2})([A-Z0-9]{9}))(\d{1})$/
|
13
|
-
end
|
14
|
-
|
15
11
|
def valid_checksum?(value)
|
16
|
-
|
12
|
+
characters = value.chars
|
13
|
+
digits = characters.map { |character| character.match(/[A-Z]/) ? (character.ord - 55) : character.to_i }
|
17
14
|
even_values = digits.values_at(* digits.each_index.select { |i| i.even? })
|
18
15
|
odd_values = digits.values_at(* digits.each_index.select { |i| i.odd? })
|
19
16
|
|
20
|
-
longest, shortest =
|
21
|
-
[even_values, odd_values]
|
22
|
-
else
|
23
|
-
[odd_values, even_values]
|
24
|
-
end
|
17
|
+
longest, shortest = (even_values.last == characters.map(&:to_i)) ? [even_values, odd_values] : [odd_values, even_values]
|
25
18
|
|
26
19
|
longest = longest.map { |i| i * 2 }
|
27
|
-
values =
|
28
|
-
|
20
|
+
values = longest.concat(shortest).to_s.scan(/./).map(&:to_i)
|
21
|
+
total = values.inject(&:+)
|
22
|
+
|
23
|
+
(10 - (total % 10)) % 10
|
24
|
+
end
|
25
|
+
|
26
|
+
def valid_format?(value)
|
27
|
+
value =~ /^((AF|AX|AL|DZ|AS|AD|AO|AI|AQ|AG|AR|AM|AW|AU|AT|AZ|BS|BH|BD|BB|BY|BE|BZ|BJ|BM|BT|BO|BQ|BA|BW|BV|BR|IO|BN|BG|BF|BI|KH|CM|CA|CV|KY|CF|TD|CL|CN|CX|CC|CO|KM|CG|CD|CK|CR|CI|HR|CU|CW|CY|CZ|DK|DJ|DM|DO|EC|EG|SV|GQ|ER|EE|ET|FK|FO|FJ|FI|FR|GF|PF|TF|GA|GM|GE|DE|GH|GI|GR|GL|GD|GP|GU|GT|GG|GN|GW|GY|HT|HM|VA|HN|HK|HU|IS|IN|ID|IR|IQ|IE|IM|IL|IT|JM|JP|JE|JO|KZ|KE|KI|KP|KR|KW|KG|LA|LV|LB|LS|LR|LY|LI|LT|LU|MO|MK|MG|MW|MY|MV|ML|MT|MH|MQ|MR|MU|YT|MX|FM|MD|MC|MN|ME|MS|MA|MZ|MM|NA|NR|NP|NL|NC|NZ|NI|NE|NG|NU|NF|MP|NO|OM|PK|PW|PS|PA|PG|PY|PE|PH|PN|PL|PT|PR|QA|RE|RO|RU|RW|BL|SH|KN|LC|MF|PM|VC|WS|SM|ST|SA|SN|RS|SC|SL|SG|SX|SK|SI|SB|SO|ZA|GS|SS|ES|LK|SD|SR|SJ|SZ|SE|CH|SY|TW|TJ|TZ|TH|TL|TG|TK|TO|TT|TN|TR|TM|TC|TV|UG|UA|AE|GB|US|UM|UY|UZ|VU|VE|VN|VG|VI|WF|EH|YE|ZM|ZW{2})([A-Z0-9]{9}))(\d{1})$/
|
28
|
+
end
|
29
29
|
|
30
|
-
|
30
|
+
def valid_length?(value)
|
31
|
+
value.present?
|
31
32
|
end
|
32
33
|
|
33
34
|
def valid?(value)
|
35
|
+
valid_length?(value) &&
|
34
36
|
valid_format?(value) &&
|
35
37
|
valid_checksum?(value)
|
36
38
|
end
|
@@ -1,23 +1,37 @@
|
|
1
1
|
class MacAddressValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
unless valid?(value)
|
4
|
+
unless valid?(value.to_s)
|
5
5
|
record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.mac_address'))
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
9
|
private
|
10
10
|
|
11
|
+
DEFAULT_FORMATS = [
|
12
|
+
/^([\h]{2}:){5}[\h]{2}?$/i,
|
13
|
+
/^([\h]{2}[-|\.|\s]){5}[\h]{2}?$/i,
|
14
|
+
/^([\h]{6})[-|\.][\h]{6}?$/i,
|
15
|
+
/^([\h]{6}):[\h]{6}?$/i,
|
16
|
+
/^([\h]{4}[-|\.|\s]){2}[\h]{4}?$/i,
|
17
|
+
/^[\h]{12}?$/i
|
18
|
+
]
|
19
|
+
|
11
20
|
def valid_format?(value)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
(
|
21
|
+
result = false
|
22
|
+
DEFAULT_FORMATS.each do |pattern|
|
23
|
+
result = (value =~ pattern)
|
24
|
+
break if result
|
25
|
+
end
|
26
|
+
return(result)
|
27
|
+
end
|
28
|
+
|
29
|
+
def valid_length?(value)
|
30
|
+
value.present?
|
18
31
|
end
|
19
32
|
|
20
33
|
def valid?(value)
|
34
|
+
valid_length?(value) &&
|
21
35
|
valid_format?(value)
|
22
36
|
end
|
23
37
|
|
@@ -1,9 +1,24 @@
|
|
1
1
|
class NameValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
unless value
|
4
|
+
unless valid?(value.to_s)
|
5
5
|
record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.name'))
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
+
private
|
10
|
+
|
11
|
+
def valid_format?(value)
|
12
|
+
value =~ /\A([a-zA-Z'-]+\s+){1,4}[a-zA-Z'-]*\z/i
|
13
|
+
end
|
14
|
+
|
15
|
+
def valid_length?(value)
|
16
|
+
value.present?
|
17
|
+
end
|
18
|
+
|
19
|
+
def valid?(value)
|
20
|
+
valid_length?(value) &&
|
21
|
+
valid_format?(value)
|
22
|
+
end
|
23
|
+
|
9
24
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class PasswordValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
unless valid?(value, options)
|
4
|
+
unless valid?(value.to_s, options)
|
5
5
|
record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.password'))
|
6
6
|
end
|
7
7
|
end
|
@@ -9,14 +9,15 @@ class PasswordValidator < ActiveModel::EachValidator
|
|
9
9
|
private
|
10
10
|
|
11
11
|
def valid_format?(value, options)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
value =~ (options.fetch(:strict, false) ? /^(?=^.{1,255}$)((?=.*[A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z]))^.*$/ : /^[a-z0-9!@#$%^&*_-]{1,255}$/)
|
13
|
+
end
|
14
|
+
|
15
|
+
def valid_length?(value)
|
16
|
+
value.present?
|
17
17
|
end
|
18
18
|
|
19
19
|
def valid?(value, options)
|
20
|
+
valid_length?(value) &&
|
20
21
|
valid_format?(value, options)
|
21
22
|
end
|
22
23
|
|
@@ -1,9 +1,24 @@
|
|
1
1
|
class PhoneValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
unless value
|
4
|
+
unless valid?(value.to_s)
|
5
5
|
record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.phone'))
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
+
private
|
10
|
+
|
11
|
+
def valid_format?(value)
|
12
|
+
value =~ /^[0-9+\(\)#\.\s\/ext-]+$/i
|
13
|
+
end
|
14
|
+
|
15
|
+
def valid_length?(value)
|
16
|
+
value.present?
|
17
|
+
end
|
18
|
+
|
19
|
+
def valid?(value)
|
20
|
+
valid_length?(value) &&
|
21
|
+
valid_format?(value)
|
22
|
+
end
|
23
|
+
|
9
24
|
end
|
@@ -1,30 +1,35 @@
|
|
1
1
|
class SedolValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
unless valid?(value)
|
4
|
+
unless valid?(value.to_s)
|
5
5
|
record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.sedol'))
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
9
|
private
|
10
10
|
|
11
|
-
def valid_format?(value)
|
12
|
-
value =~ /^([A-Z0-9]{6})(\d{1})$/
|
13
|
-
end
|
14
|
-
|
15
11
|
def valid_checksum?(value)
|
16
|
-
digits = value.
|
12
|
+
digits = value.chars.map { |digit| digit.match(/[A-Z]/) ? (digit.ord - 55) : digit.to_i }
|
17
13
|
weights = [1, 3, 1, 7, 3, 9, 1]
|
18
|
-
sum = 0
|
19
14
|
|
20
|
-
|
21
|
-
|
15
|
+
total = 0
|
16
|
+
digits.each_with_index do |digit, i|
|
17
|
+
total += (weights[i] * digit)
|
22
18
|
end
|
23
19
|
|
24
|
-
(10 -
|
20
|
+
(10 - total % 10) % 10
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid_format?(value)
|
24
|
+
value =~ /^([A-Z0-9]{6})(\d{1})$/
|
25
|
+
end
|
26
|
+
|
27
|
+
def valid_length?(value)
|
28
|
+
value.present?
|
25
29
|
end
|
26
30
|
|
27
31
|
def valid?(value)
|
32
|
+
valid_length?(value) &&
|
28
33
|
valid_format?(value) &&
|
29
34
|
valid_checksum?(value)
|
30
35
|
end
|
@@ -1,9 +1,24 @@
|
|
1
1
|
class SlugValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
unless value
|
4
|
+
unless valid?(value.to_s)
|
5
5
|
record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.slug'))
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
+
private
|
10
|
+
|
11
|
+
def valid_format?(value)
|
12
|
+
value =~ /^[a-z0-9_-]+$/
|
13
|
+
end
|
14
|
+
|
15
|
+
def valid_length?(value)
|
16
|
+
value.present?
|
17
|
+
end
|
18
|
+
|
19
|
+
def valid?(value)
|
20
|
+
valid_length?(value) &&
|
21
|
+
valid_format?(value)
|
22
|
+
end
|
23
|
+
|
9
24
|
end
|
@@ -1,9 +1,24 @@
|
|
1
1
|
class SsnValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
unless value
|
4
|
+
unless valid?(value.to_s)
|
5
5
|
record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.ssn'))
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
+
private
|
10
|
+
|
11
|
+
def valid_format?(value)
|
12
|
+
value =~ /^\A([\d]{3}\-[\d]{2}\-[\d]{4}|[\d]{9})\Z$/
|
13
|
+
end
|
14
|
+
|
15
|
+
def valid_length?(value)
|
16
|
+
value.present?
|
17
|
+
end
|
18
|
+
|
19
|
+
def valid?(value)
|
20
|
+
valid_length?(value) &&
|
21
|
+
valid_format?(value)
|
22
|
+
end
|
23
|
+
|
9
24
|
end
|