active_validation 4.0.0 → 4.0.1
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/lib/active_validation.rb +5 -4
- data/lib/active_validation/railtie.rb +3 -3
- data/lib/active_validation/validators/alpha_numeric_validator.rb +5 -5
- data/lib/active_validation/validators/alpha_validator.rb +5 -5
- data/lib/active_validation/validators/base64_validator.rb +5 -5
- data/lib/active_validation/validators/boolean_validator.rb +5 -6
- data/lib/active_validation/validators/coordinate_validator.rb +11 -10
- data/lib/active_validation/validators/credit_card_validator.rb +31 -25
- data/lib/active_validation/validators/currency_validator.rb +5 -5
- data/lib/active_validation/validators/cusip_validator.rb +6 -5
- data/lib/active_validation/validators/email_validator.rb +6 -5
- data/lib/active_validation/validators/equality_validator.rb +10 -7
- data/lib/active_validation/validators/hex_validator.rb +5 -5
- data/lib/active_validation/validators/imei_validator.rb +6 -5
- data/lib/active_validation/validators/ip_validator.rb +5 -5
- data/lib/active_validation/validators/isbn_validator.rb +8 -8
- data/lib/active_validation/validators/isin_validator.rb +6 -5
- data/lib/active_validation/validators/mac_address_validator.rb +14 -11
- data/lib/active_validation/validators/name_validator.rb +5 -5
- data/lib/active_validation/validators/password_validator.rb +5 -5
- data/lib/active_validation/validators/phone_validator.rb +5 -5
- data/lib/active_validation/validators/sedol_validator.rb +9 -7
- data/lib/active_validation/validators/slug_validator.rb +5 -5
- data/lib/active_validation/validators/ssn_validator.rb +5 -5
- data/lib/active_validation/validators/tracking_number_validator.rb +34 -30
- data/lib/active_validation/validators/type_validator.rb +3 -4
- data/lib/active_validation/validators/url_validator.rb +2 -2
- data/lib/active_validation/validators/username_validator.rb +5 -5
- data/lib/active_validation/validators/uuid_validator.rb +5 -5
- data/lib/active_validation/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d932970843f5d25f14117bd66f2f2ec3903324bb
|
4
|
+
data.tar.gz: 0c8572a51416a466cc3cb4f313952e4f75447de0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '08d6ca92e810dbaebea9fa97bc861dcce0028d803e94bd76846ab080be3128787dad3a6ebd97b1dc804ff5564cfb019a10ebd4e52acb83e142045738658444ad'
|
7
|
+
data.tar.gz: c708bc6a229f45bf94a1fe7497d7b311259184a1e04f13321d8011f02f8019fa2bcfd7d2fe11d47c3710f1d228315a972fdbbf8cf61b79319ce43ea3c320e7f2
|
data/lib/active_validation.rb
CHANGED
@@ -6,10 +6,11 @@ require 'active_support'
|
|
6
6
|
require "active_validation/#{file_name}"
|
7
7
|
end
|
8
8
|
|
9
|
-
%w(
|
9
|
+
ACTIVE_VALIDATION_VALIDATORS ||= %w(
|
10
10
|
alpha alpha_numeric base64 boolean coordinate credit_card currency cusip email equality hex imei
|
11
11
|
ip isbn isin mac_address name password phone sedol slug ssn tracking_number type url username uuid
|
12
12
|
)
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
|
14
|
+
ACTIVE_VALIDATION_VALIDATORS.each do |file_name|
|
15
|
+
require "active_validation/validators/#{file_name}_validator"
|
16
|
+
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
class AlphaNumericValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
4
|
+
return if valid?(value.to_s, options)
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.alpha_numeric'))
|
8
7
|
end
|
9
8
|
|
10
9
|
private
|
@@ -27,7 +26,8 @@ class AlphaNumericValidator < ActiveModel::EachValidator
|
|
27
26
|
end
|
28
27
|
|
29
28
|
def valid?(value, options)
|
30
|
-
valid_length?(value) &&
|
29
|
+
valid_length?(value) &&
|
30
|
+
valid_format?(value, options)
|
31
31
|
end
|
32
32
|
|
33
33
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
class AlphaValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
4
|
+
return if valid?(value.to_s, options)
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.alpha'))
|
8
7
|
end
|
9
8
|
|
10
9
|
private
|
@@ -27,7 +26,8 @@ class AlphaValidator < ActiveModel::EachValidator
|
|
27
26
|
end
|
28
27
|
|
29
28
|
def valid?(value, options)
|
30
|
-
valid_length?(value) &&
|
29
|
+
valid_length?(value) &&
|
30
|
+
valid_format?(value, options)
|
31
31
|
end
|
32
32
|
|
33
33
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
class Base64Validator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
4
|
+
return if valid?(value.to_s)
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.base64'))
|
8
7
|
end
|
9
8
|
|
10
9
|
private
|
@@ -18,7 +17,8 @@ class Base64Validator < ActiveModel::EachValidator
|
|
18
17
|
end
|
19
18
|
|
20
19
|
def valid?(value)
|
21
|
-
valid_length?(value) &&
|
20
|
+
valid_length?(value) &&
|
21
|
+
valid_format?(value)
|
22
22
|
end
|
23
23
|
|
24
24
|
end
|
@@ -1,12 +1,11 @@
|
|
1
1
|
class BooleanValidator < ActiveModel::EachValidator
|
2
|
-
FALSE_VALUES
|
3
|
-
TRUE_VALUES
|
2
|
+
FALSE_VALUES ||= [false, 0, '0', 'f', 'F', 'false', 'FALSE'].freeze
|
3
|
+
TRUE_VALUES ||= [true, 1, '1', 't', 'T', 'true', 'TRUE'].freeze
|
4
4
|
|
5
5
|
def validate_each(record, attribute, value)
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
6
|
+
return if TRUE_VALUES.include?(value) || FALSE_VALUES.include?(value)
|
7
|
+
record.errors[attribute] <<
|
8
|
+
(options[:message] || I18n.t('active_validation.errors.messages.boolean'))
|
10
9
|
end
|
11
10
|
|
12
11
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
class CoordinateValidator < ActiveModel::EachValidator
|
2
2
|
|
3
|
+
BOUNDARIES ||= [:coordinate, :latitude, :longitude].freeze
|
4
|
+
|
3
5
|
# rubocop:disable Metrics/LineLength
|
4
6
|
def validate_each(record, attribute, value)
|
5
7
|
boundary = options[:boundary] || :coordinate
|
@@ -8,19 +10,16 @@ class CoordinateValidator < ActiveModel::EachValidator
|
|
8
10
|
"Unknown boundary: #{boundary.inspect}. Valid boundaries are: #{BOUNDARIES.map(&:inspect).join(', ')}"
|
9
11
|
end
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
13
|
+
return if valid?(value, options)
|
14
|
+
record.errors[attribute] <<
|
15
|
+
(options[:message] || I18n.t("active_validation.errors.messages.coordinate.#{boundary}"))
|
15
16
|
end
|
16
17
|
# rubocop:enable Metrics/LineLength
|
17
18
|
|
18
19
|
private
|
19
20
|
|
20
|
-
BOUNDARIES = [:coordinate, :latitude, :longitude].freeze
|
21
|
-
|
22
21
|
def valid_latitude?(value)
|
23
|
-
value >= -90 && value <= 90
|
22
|
+
value >= -90.0 && value <= 90.0
|
24
23
|
end
|
25
24
|
|
26
25
|
def valid_length?(value)
|
@@ -28,7 +27,7 @@ class CoordinateValidator < ActiveModel::EachValidator
|
|
28
27
|
end
|
29
28
|
|
30
29
|
def valid_longitude?(value)
|
31
|
-
value >= -180 && value <= 180
|
30
|
+
value >= -180.0 && value <= 180.0
|
32
31
|
end
|
33
32
|
|
34
33
|
def valid_boundary?(value, options)
|
@@ -38,12 +37,14 @@ class CoordinateValidator < ActiveModel::EachValidator
|
|
38
37
|
when :longitude
|
39
38
|
valid_longitude?(value)
|
40
39
|
else
|
41
|
-
valid_latitude?(value.first) &&
|
40
|
+
valid_latitude?(value.first) &&
|
41
|
+
valid_longitude?(value.last)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
45
|
def valid?(value, options)
|
46
|
-
valid_length?(value) &&
|
46
|
+
valid_length?(value) &&
|
47
|
+
valid_boundary?(value, options)
|
47
48
|
end
|
48
49
|
|
49
50
|
end
|
@@ -1,22 +1,20 @@
|
|
1
1
|
class CreditCardValidator < ActiveModel::EachValidator
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
laser: [16, 17, 18, 19], maestro: [12, 13, 14, 15, 16, 17, 18, 19],
|
15
|
-
mastercard: [16], solo: [16, 18, 19], unionpay: [16, 17, 18, 19], visa: [16]
|
3
|
+
LENGTHS ||= {
|
4
|
+
american_express: [15],
|
5
|
+
diners_club: [14, 16],
|
6
|
+
discover: [16],
|
7
|
+
jcb: [16],
|
8
|
+
laser: [16, 17, 18, 19],
|
9
|
+
maestro: [12, 13, 14, 15, 16, 17, 18, 19],
|
10
|
+
mastercard: [16],
|
11
|
+
solo: [16, 18, 19],
|
12
|
+
unionpay: [16, 17, 18, 19],
|
13
|
+
visa: [16]
|
16
14
|
}.freeze
|
17
15
|
|
18
16
|
# rubocop:disable Style/IndentArray
|
19
|
-
|
17
|
+
PREFIXES ||= {
|
20
18
|
american_express: %w(34 37),
|
21
19
|
diners_club: %w(300 301 302 303 304 305 36 54 55),
|
22
20
|
discover: %w(
|
@@ -37,6 +35,14 @@ class CreditCardValidator < ActiveModel::EachValidator
|
|
37
35
|
}.freeze
|
38
36
|
# rubocop:enable Style/IndentArray
|
39
37
|
|
38
|
+
def validate_each(record, attribute, value)
|
39
|
+
return if valid?(value.to_s, options)
|
40
|
+
record.errors[attribute] <<
|
41
|
+
(options[:message] || I18n.t('active_validation.errors.messages.credit_card'))
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
40
46
|
def valid_format?(value, options)
|
41
47
|
value =~ (options[:strict] ? /^[0-9]+$/ : /^[0-9 -.]+$/)
|
42
48
|
end
|
@@ -44,37 +50,37 @@ class CreditCardValidator < ActiveModel::EachValidator
|
|
44
50
|
def valid_length?(value, options)
|
45
51
|
return(false) unless value.present?
|
46
52
|
|
47
|
-
|
53
|
+
card = options[:card] || :all
|
48
54
|
value_size = value.size
|
49
55
|
|
50
|
-
case
|
56
|
+
case card
|
51
57
|
when :amex
|
52
|
-
|
58
|
+
LENGTHS[:american_express].include?(value_size)
|
53
59
|
when :all
|
54
|
-
value_size_range =
|
60
|
+
value_size_range = LENGTHS.values.flatten.uniq.sort
|
55
61
|
value_size.between?(value_size_range.first, value_size_range.last)
|
56
62
|
else
|
57
|
-
|
63
|
+
LENGTHS[card].include?(value_size)
|
58
64
|
end
|
59
65
|
end
|
60
66
|
|
61
67
|
def valid_prefix?(value, options)
|
62
|
-
|
68
|
+
card = options[:card] || :all
|
63
69
|
|
64
|
-
case
|
70
|
+
case card
|
65
71
|
when :amex
|
66
|
-
|
72
|
+
PREFIXES[:american_express].any? { |pat| value.start_with?(pat) }
|
67
73
|
when :all
|
68
74
|
result = false
|
69
|
-
|
75
|
+
LENGTHS.each do |key, values|
|
70
76
|
if values.include?(value.size)
|
71
|
-
result =
|
77
|
+
result = PREFIXES[key].any? { |pat| value.start_with?(pat) }
|
72
78
|
break if result
|
73
79
|
end
|
74
80
|
end
|
75
81
|
result
|
76
82
|
else
|
77
|
-
|
83
|
+
PREFIXES[card].any? { |pat| value.start_with?(pat) }
|
78
84
|
end
|
79
85
|
end
|
80
86
|
|
@@ -1,10 +1,9 @@
|
|
1
1
|
class CurrencyValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
4
|
+
return if valid?(value.to_s, options)
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.currency'))
|
8
7
|
end
|
9
8
|
|
10
9
|
private
|
@@ -18,7 +17,8 @@ class CurrencyValidator < ActiveModel::EachValidator
|
|
18
17
|
end
|
19
18
|
|
20
19
|
def valid?(value, options)
|
21
|
-
valid_length?(value) &&
|
20
|
+
valid_length?(value) &&
|
21
|
+
valid_format?(value, options)
|
22
22
|
end
|
23
23
|
|
24
24
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
class CusipValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
4
|
+
return if valid?(value.to_s)
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.cusip'))
|
8
7
|
end
|
9
8
|
|
10
9
|
private
|
@@ -30,7 +29,9 @@ class CusipValidator < ActiveModel::EachValidator
|
|
30
29
|
end
|
31
30
|
|
32
31
|
def valid?(value)
|
33
|
-
valid_length?(value) &&
|
32
|
+
valid_length?(value) &&
|
33
|
+
valid_format?(value) &&
|
34
|
+
valid_checksum?(value)
|
34
35
|
end
|
35
36
|
|
36
37
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
class EmailValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
4
|
+
return if valid?(value.to_s, options)
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.email'))
|
8
7
|
end
|
9
8
|
|
10
9
|
private
|
@@ -24,7 +23,9 @@ class EmailValidator < ActiveModel::EachValidator
|
|
24
23
|
def valid?(value, options)
|
25
24
|
options = [*(options[:domain])]
|
26
25
|
|
27
|
-
valid_length?(value) &&
|
26
|
+
valid_length?(value) &&
|
27
|
+
valid_format?(value) &&
|
28
|
+
valid_domain?(value, options)
|
28
29
|
end
|
29
30
|
|
30
31
|
end
|
@@ -1,8 +1,12 @@
|
|
1
1
|
class EqualityValidator < ActiveModel::EachValidator
|
2
2
|
|
3
|
-
OPERATORS
|
4
|
-
less_than: :<,
|
5
|
-
|
3
|
+
OPERATORS ||= {
|
4
|
+
less_than: :<,
|
5
|
+
less_than_or_equal_to: :<=,
|
6
|
+
greater_than: :>,
|
7
|
+
greater_than_or_equal_to: :>=,
|
8
|
+
equal_to: :==,
|
9
|
+
not_equal_to: :!=
|
6
10
|
}.freeze
|
7
11
|
|
8
12
|
# rubocop:disable Metrics/LineLength
|
@@ -21,10 +25,9 @@ class EqualityValidator < ActiveModel::EachValidator
|
|
21
25
|
end
|
22
26
|
|
23
27
|
operator = OPERATORS[operator]
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
28
|
+
return if value.send(operator, record.send(to))
|
29
|
+
record.errors[attribute] <<
|
30
|
+
(options[:message] || I18n.t('active_validation.errors.messages.equality', attr: to, operator: operator))
|
28
31
|
end
|
29
32
|
# rubocop:enable Metrics/LineLength
|
30
33
|
|
@@ -1,10 +1,9 @@
|
|
1
1
|
class HexValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
4
|
+
return if valid?(value.to_s)
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.hex'))
|
8
7
|
end
|
9
8
|
|
10
9
|
private
|
@@ -18,7 +17,8 @@ class HexValidator < ActiveModel::EachValidator
|
|
18
17
|
end
|
19
18
|
|
20
19
|
def valid?(value)
|
21
|
-
valid_length?(value) &&
|
20
|
+
valid_length?(value) &&
|
21
|
+
valid_format?(value)
|
22
22
|
end
|
23
23
|
|
24
24
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
class ImeiValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
4
|
+
return if valid?(value.to_s)
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.imei'))
|
8
7
|
end
|
9
8
|
|
10
9
|
private
|
@@ -32,7 +31,9 @@ class ImeiValidator < ActiveModel::EachValidator
|
|
32
31
|
end
|
33
32
|
|
34
33
|
def valid?(value)
|
35
|
-
valid_length?(value) &&
|
34
|
+
valid_length?(value) &&
|
35
|
+
valid_format?(value) &&
|
36
|
+
valid_luhn?(value)
|
36
37
|
end
|
37
38
|
|
38
39
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
class IpValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
4
|
+
return if valid?(value.to_s)
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.ip'))
|
8
7
|
end
|
9
8
|
|
10
9
|
private
|
@@ -20,7 +19,8 @@ class IpValidator < ActiveModel::EachValidator
|
|
20
19
|
end
|
21
20
|
|
22
21
|
def valid?(value)
|
23
|
-
valid_length?(value) &&
|
22
|
+
valid_length?(value) &&
|
23
|
+
valid_format?(value)
|
24
24
|
end
|
25
25
|
|
26
26
|
end
|
@@ -1,21 +1,20 @@
|
|
1
1
|
class IsbnValidator < ActiveModel::EachValidator
|
2
2
|
|
3
|
+
CHARACTERS ||= %w(0 1 2 3 4 5 6 7 8 9 0 x).freeze
|
4
|
+
|
3
5
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
6
|
+
return if valid?(value.to_s)
|
7
|
+
record.errors[attribute] <<
|
8
|
+
(options[:message] || I18n.t('active_validation.errors.messages.isbn'))
|
8
9
|
end
|
9
10
|
|
10
11
|
private
|
11
12
|
|
12
|
-
CHARS_VALUES = %w(0 1 2 3 4 5 6 7 8 9 0 x).freeze
|
13
|
-
|
14
13
|
def valid_format?(value)
|
15
14
|
return(false) if value.empty?
|
16
15
|
value = value.gsub(/-| /, '').downcase.chars
|
17
16
|
|
18
|
-
[10, 13].include?(value.size) && value.all? { |chr|
|
17
|
+
[10, 13].include?(value.size) && value.all? { |chr| CHARACTERS.include?(chr) }
|
19
18
|
end
|
20
19
|
|
21
20
|
def valid_length?(value)
|
@@ -23,7 +22,8 @@ class IsbnValidator < ActiveModel::EachValidator
|
|
23
22
|
end
|
24
23
|
|
25
24
|
def valid?(value)
|
26
|
-
valid_length?(value) &&
|
25
|
+
valid_length?(value) &&
|
26
|
+
valid_format?(value)
|
27
27
|
end
|
28
28
|
|
29
29
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
class IsinValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
4
|
+
return if valid?(value.to_s)
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.isin'))
|
8
7
|
end
|
9
8
|
|
10
9
|
private
|
@@ -39,7 +38,9 @@ class IsinValidator < ActiveModel::EachValidator
|
|
39
38
|
end
|
40
39
|
|
41
40
|
def valid?(value)
|
42
|
-
valid_length?(value) &&
|
41
|
+
valid_length?(value) &&
|
42
|
+
valid_format?(value) &&
|
43
|
+
valid_checksum?(value)
|
43
44
|
end
|
44
45
|
|
45
46
|
end
|
@@ -1,20 +1,22 @@
|
|
1
1
|
class MacAddressValidator < ActiveModel::EachValidator
|
2
2
|
|
3
|
+
DEFAULT_FORMATS ||= [
|
4
|
+
/^([\h]{2}:){5}[\h]{2}?$/i,
|
5
|
+
/^([\h]{2}[-|\.|\s]){5}[\h]{2}?$/i,
|
6
|
+
/^([\h]{6})[-|\.][\h]{6}?$/i,
|
7
|
+
/^([\h]{6}):[\h]{6}?$/i,
|
8
|
+
/^([\h]{4}[-|\.|\s]){2}[\h]{4}?$/i,
|
9
|
+
/^[\h]{12}?$/i
|
10
|
+
].freeze
|
11
|
+
|
3
12
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
13
|
+
return if valid?(value.to_s)
|
14
|
+
record.errors[attribute] <<
|
15
|
+
(options[:message] || I18n.t('active_validation.errors.messages.mac_address'))
|
8
16
|
end
|
9
17
|
|
10
18
|
private
|
11
19
|
|
12
|
-
DEFAULT_FORMATS = [
|
13
|
-
/^([\h]{2}:){5}[\h]{2}?$/i, /^([\h]{2}[-|\.|\s]){5}[\h]{2}?$/i,
|
14
|
-
/^([\h]{6})[-|\.][\h]{6}?$/i, /^([\h]{6}):[\h]{6}?$/i,
|
15
|
-
/^([\h]{4}[-|\.|\s]){2}[\h]{4}?$/i, /^[\h]{12}?$/i
|
16
|
-
].freeze
|
17
|
-
|
18
20
|
def valid_format?(value)
|
19
21
|
result = false
|
20
22
|
DEFAULT_FORMATS.each do |pat|
|
@@ -29,7 +31,8 @@ class MacAddressValidator < ActiveModel::EachValidator
|
|
29
31
|
end
|
30
32
|
|
31
33
|
def valid?(value)
|
32
|
-
valid_length?(value) &&
|
34
|
+
valid_length?(value) &&
|
35
|
+
valid_format?(value)
|
33
36
|
end
|
34
37
|
|
35
38
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
class NameValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
4
|
+
return if valid?(value.to_s)
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.name'))
|
8
7
|
end
|
9
8
|
|
10
9
|
private
|
@@ -18,7 +17,8 @@ class NameValidator < ActiveModel::EachValidator
|
|
18
17
|
end
|
19
18
|
|
20
19
|
def valid?(value)
|
21
|
-
valid_length?(value) &&
|
20
|
+
valid_length?(value) &&
|
21
|
+
valid_format?(value)
|
22
22
|
end
|
23
23
|
|
24
24
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
class PasswordValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
4
|
+
return if valid?(value.to_s, options)
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.password'))
|
8
7
|
end
|
9
8
|
|
10
9
|
private
|
@@ -22,7 +21,8 @@ class PasswordValidator < ActiveModel::EachValidator
|
|
22
21
|
end
|
23
22
|
|
24
23
|
def valid?(value, options)
|
25
|
-
valid_length?(value) &&
|
24
|
+
valid_length?(value) &&
|
25
|
+
valid_format?(value, options)
|
26
26
|
end
|
27
27
|
|
28
28
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
class PhoneValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
4
|
+
return if valid?(value.to_s)
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.phone'))
|
8
7
|
end
|
9
8
|
|
10
9
|
private
|
@@ -18,7 +17,8 @@ class PhoneValidator < ActiveModel::EachValidator
|
|
18
17
|
end
|
19
18
|
|
20
19
|
def valid?(value)
|
21
|
-
valid_length?(value) &&
|
20
|
+
valid_length?(value) &&
|
21
|
+
valid_format?(value)
|
22
22
|
end
|
23
23
|
|
24
24
|
end
|
@@ -1,20 +1,20 @@
|
|
1
1
|
class SedolValidator < ActiveModel::EachValidator
|
2
2
|
|
3
|
+
WEIGHTS ||= [1, 3, 1, 7, 3, 9, 1].freeze
|
4
|
+
|
3
5
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
6
|
+
return if valid?(value.to_s)
|
7
|
+
record.errors[attribute] <<
|
8
|
+
(options[:message] || I18n.t('active_validation.errors.messages.sedol'))
|
8
9
|
end
|
9
10
|
|
10
11
|
private
|
11
12
|
|
12
13
|
def valid_checksum?(value)
|
13
14
|
digits = value.chars.map { |dgt| dgt =~ /[A-Z]/ ? (dgt.ord - 55) : dgt.to_i }
|
14
|
-
weights = [1, 3, 1, 7, 3, 9, 1]
|
15
15
|
|
16
16
|
total = 0
|
17
|
-
digits.each_with_index { |dgt, idx| total += (
|
17
|
+
digits.each_with_index { |dgt, idx| total += (WEIGHTS[idx] * dgt) }
|
18
18
|
|
19
19
|
(10 - total % 10) % 10
|
20
20
|
end
|
@@ -28,7 +28,9 @@ class SedolValidator < ActiveModel::EachValidator
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def valid?(value)
|
31
|
-
valid_length?(value) &&
|
31
|
+
valid_length?(value) &&
|
32
|
+
valid_format?(value) &&
|
33
|
+
valid_checksum?(value)
|
32
34
|
end
|
33
35
|
|
34
36
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
class SlugValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
4
|
+
return if valid?(value.to_s)
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.slug'))
|
8
7
|
end
|
9
8
|
|
10
9
|
private
|
@@ -18,7 +17,8 @@ class SlugValidator < ActiveModel::EachValidator
|
|
18
17
|
end
|
19
18
|
|
20
19
|
def valid?(value)
|
21
|
-
valid_length?(value) &&
|
20
|
+
valid_length?(value) &&
|
21
|
+
valid_format?(value)
|
22
22
|
end
|
23
23
|
|
24
24
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
class SsnValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
4
|
+
return if valid?(value.to_s)
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.ssn'))
|
8
7
|
end
|
9
8
|
|
10
9
|
private
|
@@ -18,7 +17,8 @@ class SsnValidator < ActiveModel::EachValidator
|
|
18
17
|
end
|
19
18
|
|
20
19
|
def valid?(value)
|
21
|
-
valid_length?(value) &&
|
20
|
+
valid_length?(value) &&
|
21
|
+
valid_format?(value)
|
22
22
|
end
|
23
23
|
|
24
24
|
end
|
@@ -1,18 +1,13 @@
|
|
1
1
|
class TrackingNumberValidator < ActiveModel::EachValidator
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
private
|
11
|
-
|
12
|
-
DEFAULT_CARRIERS_AND_SERVICES = {
|
13
|
-
dhl: { express: /^([0-9]{9,9})([0-9])$/, express_air: /^([0-9]{10,10})([0-9])$/ },
|
3
|
+
CARRIERS_AND_SERVICES ||= {
|
4
|
+
dhl: {
|
5
|
+
express: /^([0-9]{9,9})([0-9])$/,
|
6
|
+
express_air: /^([0-9]{10,10})([0-9])$/
|
7
|
+
},
|
14
8
|
fedex: {
|
15
|
-
express: /^([0-9]{11,11})([0-9])$/,
|
9
|
+
express: /^([0-9]{11,11})([0-9])$/,
|
10
|
+
ground: /^([0-9]{14,14})([0-9])$/,
|
16
11
|
ground18: /^[0-9]{2,2}([0-9]{15,15})([0-9])$/,
|
17
12
|
ground96: /^96[0-9]{5,5}([0-9]{14,14})([0-9])$/,
|
18
13
|
smart_post: /^((?:92)?[0-9]{5}[0-9]{14})([0-9])$/
|
@@ -26,10 +21,18 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
26
21
|
}
|
27
22
|
}.freeze
|
28
23
|
|
24
|
+
def validate_each(record, attribute, value)
|
25
|
+
return if valid?(value.to_s, options)
|
26
|
+
record.errors[attribute] <<
|
27
|
+
(options[:message] || I18n.t('active_validation.errors.messages.tracking_number'))
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
29
32
|
# DHL
|
30
|
-
|
31
|
-
define_method("valid_dhl_#{
|
32
|
-
formula =
|
33
|
+
CARRIERS_AND_SERVICES[:dhl].each do |srv, pat|
|
34
|
+
define_method("valid_dhl_#{srv}_checksum?") do |val|
|
35
|
+
formula = val.scan(pat).flatten.compact
|
33
36
|
return(false) if formula.empty?
|
34
37
|
sequence, check_digit = formula.map(&:to_i)
|
35
38
|
|
@@ -41,7 +44,7 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
41
44
|
def valid_fedex_express_checksum?(value)
|
42
45
|
return(false) unless value.size == 12
|
43
46
|
|
44
|
-
pattern =
|
47
|
+
pattern = CARRIERS_AND_SERVICES[:fedex][:express]
|
45
48
|
formula = value.scan(pattern).flatten.compact
|
46
49
|
return(false) if formula.empty?
|
47
50
|
sequence, check_digit = formula
|
@@ -54,7 +57,7 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
54
57
|
(total % 11 % 10) == check_digit.to_i
|
55
58
|
end
|
56
59
|
|
57
|
-
|
60
|
+
CARRIERS_AND_SERVICES[:fedex]
|
58
61
|
.select { |key, _| [:ground, :ground18, :ground96].include?(key) }
|
59
62
|
.each_with_index do |(srv, pat), idx|
|
60
63
|
define_method("valid_fedex_#{srv}_checksum?") do |val|
|
@@ -81,14 +84,14 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
81
84
|
value = "92#{value}" unless value =~ /^92/
|
82
85
|
return(false) unless value.size == 22
|
83
86
|
|
84
|
-
pattern =
|
87
|
+
pattern = CARRIERS_AND_SERVICES[:fedex][:smart_post]
|
85
88
|
formula = value.scan(pattern).flatten.compact
|
86
89
|
return(false) if formula.empty?
|
87
90
|
sequence, check_digit = formula
|
88
91
|
|
89
92
|
total = 0
|
90
|
-
sequence.chars.reverse.each_with_index do |
|
91
|
-
result =
|
93
|
+
sequence.chars.reverse.each_with_index do |chr, idx|
|
94
|
+
result = chr.to_i
|
92
95
|
result *= 3 if idx.even?
|
93
96
|
total += result
|
94
97
|
end
|
@@ -99,14 +102,14 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
99
102
|
end
|
100
103
|
|
101
104
|
# Ontrac & UPS
|
102
|
-
|
105
|
+
CARRIERS_AND_SERVICES
|
103
106
|
.select { |key, _| [:ontrac, :ups].include?(key) }
|
104
107
|
.each_with_index do |(cars, sers), idx|
|
105
108
|
sers.each do |ser, pat|
|
106
|
-
define_method("valid_#{cars}_#{ser}_checksum?") do |
|
107
|
-
return(false) unless
|
109
|
+
define_method("valid_#{cars}_#{ser}_checksum?") do |val|
|
110
|
+
return(false) unless val.size == [15, 18].at(idx)
|
108
111
|
|
109
|
-
formula =
|
112
|
+
formula = val.scan(pat).flatten.compact
|
110
113
|
return(false) if formula.empty?
|
111
114
|
sequence, check_digit = formula
|
112
115
|
|
@@ -128,7 +131,7 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
128
131
|
def valid_usps_usps13_checksum?(value)
|
129
132
|
return(false) unless value.size == 13
|
130
133
|
|
131
|
-
pattern =
|
134
|
+
pattern = CARRIERS_AND_SERVICES[:usps][:usps13]
|
132
135
|
sequence = value.scan(pattern).flatten.compact
|
133
136
|
return(false) if sequence.empty?
|
134
137
|
|
@@ -154,7 +157,7 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
154
157
|
def valid_usps_usps20_checksum?(value)
|
155
158
|
return(false) unless value.size == 20
|
156
159
|
|
157
|
-
pattern =
|
160
|
+
pattern = CARRIERS_AND_SERVICES[:usps][:usps20]
|
158
161
|
sequence = value.scan(pattern).flatten.compact
|
159
162
|
return(false) if sequence.empty?
|
160
163
|
|
@@ -177,7 +180,7 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
177
180
|
value = "91#{value}" unless value =~ /^(420\d{5})?9[1-5]/
|
178
181
|
return(false) unless value.size == 22
|
179
182
|
|
180
|
-
pattern =
|
183
|
+
pattern = CARRIERS_AND_SERVICES[:usps][:usps91]
|
181
184
|
sequence = value.scan(pattern).flatten.compact
|
182
185
|
return(false) if sequence.empty?
|
183
186
|
|
@@ -203,7 +206,7 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
203
206
|
result = false
|
204
207
|
|
205
208
|
if carrier.nil? && service.nil?
|
206
|
-
|
209
|
+
CARRIERS_AND_SERVICES.each do |car, ser|
|
207
210
|
ser.each_key do |car_ser|
|
208
211
|
result = send("valid_#{car}_#{car_ser}_checksum?", value)
|
209
212
|
break if result
|
@@ -211,7 +214,7 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
211
214
|
break if result
|
212
215
|
end
|
213
216
|
elsif service.nil?
|
214
|
-
|
217
|
+
CARRIERS_AND_SERVICES[carrier].each_key do |car_ser|
|
215
218
|
result = send("valid_#{carrier}_#{car_ser}_checksum?", value)
|
216
219
|
break if result
|
217
220
|
end
|
@@ -227,7 +230,8 @@ class TrackingNumberValidator < ActiveModel::EachValidator
|
|
227
230
|
end
|
228
231
|
|
229
232
|
def valid?(value, options)
|
230
|
-
valid_length?(value) &&
|
233
|
+
valid_length?(value) &&
|
234
|
+
valid_checksum?(value, options)
|
231
235
|
end
|
232
236
|
|
233
237
|
end
|
@@ -5,10 +5,9 @@ end
|
|
5
5
|
class TypeValidator < ActiveModel::EachValidator
|
6
6
|
|
7
7
|
def validate_each(record, attribute, value)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
end
|
8
|
+
return if valid?(value, options)
|
9
|
+
record.errors[attribute] <<
|
10
|
+
(options[:message] || I18n.t('active_validation.errors.messages.type'))
|
12
11
|
end
|
13
12
|
|
14
13
|
private
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'uri'
|
2
2
|
class UrlValidator < ActiveModel::EachValidator
|
3
3
|
|
4
|
+
DEFAULT_SCHEMES ||= [:http, :https].freeze
|
5
|
+
|
4
6
|
def validate_each(record, attribute, value)
|
5
7
|
uri = URI.parse(value.to_s)
|
6
8
|
raise URI::InvalidURIError unless valid?(uri, options)
|
@@ -11,8 +13,6 @@ class UrlValidator < ActiveModel::EachValidator
|
|
11
13
|
|
12
14
|
private
|
13
15
|
|
14
|
-
DEFAULT_SCHEMES = [:http, :https].freeze
|
15
|
-
|
16
16
|
def valid_domain?(value, options)
|
17
17
|
value_downcased = value.host.to_s.downcase
|
18
18
|
options.empty? || options.any? { |dom| value_downcased.end_with?(".#{dom.downcase}") }
|
@@ -1,10 +1,9 @@
|
|
1
1
|
class UsernameValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
4
|
+
return if valid?(value.to_s)
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.username'))
|
8
7
|
end
|
9
8
|
|
10
9
|
private
|
@@ -18,7 +17,8 @@ class UsernameValidator < ActiveModel::EachValidator
|
|
18
17
|
end
|
19
18
|
|
20
19
|
def valid?(value)
|
21
|
-
valid_length?(value) &&
|
20
|
+
valid_length?(value) &&
|
21
|
+
valid_format?(value)
|
22
22
|
end
|
23
23
|
|
24
24
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
class UuidValidator < ActiveModel::EachValidator
|
2
2
|
|
3
3
|
def validate_each(record, attribute, value)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
end
|
4
|
+
return if valid?(value.to_s, options)
|
5
|
+
record.errors[attribute] <<
|
6
|
+
(options[:message] || I18n.t('active_validation.errors.messages.uuid'))
|
8
7
|
end
|
9
8
|
|
10
9
|
private
|
@@ -27,7 +26,8 @@ class UuidValidator < ActiveModel::EachValidator
|
|
27
26
|
end
|
28
27
|
|
29
28
|
def valid?(value, options)
|
30
|
-
valid_length?(value) &&
|
29
|
+
valid_length?(value) &&
|
30
|
+
valid_format?(value, options)
|
31
31
|
end
|
32
32
|
|
33
33
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_validation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.
|
4
|
+
version: 4.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Juan Gomez
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -227,7 +227,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
227
227
|
version: '0'
|
228
228
|
requirements: []
|
229
229
|
rubyforge_project:
|
230
|
-
rubygems_version: 2.6.
|
230
|
+
rubygems_version: 2.6.6
|
231
231
|
signing_key:
|
232
232
|
specification_version: 4
|
233
233
|
summary: Gem for commonly used validators.
|