active_validation 4.0.0 → 4.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|