can_has_validations 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +39 -1
- data/lib/can_has_validations.rb +1 -1
- data/lib/can_has_validations/locale/es.yml +12 -0
- data/lib/can_has_validations/validators/array_validator.rb +28 -3
- data/lib/can_has_validations/validators/hash_keys_validator.rb +30 -0
- data/lib/can_has_validations/validators/hash_values_validator.rb +55 -0
- data/lib/can_has_validations/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bdd7c0ba5910899942ccfa116005b0458596cd475c30495c788fbd72bf25f8f6
|
4
|
+
data.tar.gz: 1507f461b6c2a10e1084d4e7af494924b168b4db83f318eac672b9ac94b58817
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e9d0f1333fbd0f77cb45ec67c741f9b63b5609324e919830e7a4076831a2527efd222ede98fabcb4b632ccdc76fc4a4ce048f2e7bd0659504928f80e7dcdc70
|
7
|
+
data.tar.gz: c85f1eabcbe0e2579dc2ea5917d731088fa7afe0a5da14ddb8a40ccee8a94bca0c6af44405f263a978cad987ce1695e0abbe47ae7d3cfc113fccec153618d0e6
|
data/README.md
CHANGED
@@ -9,6 +9,8 @@ Validations provided:
|
|
9
9
|
* Email
|
10
10
|
* Existence
|
11
11
|
* Grandparent
|
12
|
+
* Hash Keys
|
13
|
+
* Hash Values
|
12
14
|
* Hostname
|
13
15
|
* IP address
|
14
16
|
* Ordering
|
@@ -135,6 +137,42 @@ or the database foreign key (`:user_id`). You can also use any other field. The
|
|
135
137
|
test is merely that they match, not that they are associations.
|
136
138
|
|
137
139
|
|
140
|
+
## Hash Keys validator ##
|
141
|
+
|
142
|
+
Many databases now allow storing hashes. This validates the keys of those
|
143
|
+
hashes. It is conceptually the same as using the Array validator to validate
|
144
|
+
`hash_attribute.keys`.
|
145
|
+
|
146
|
+
It is able to use most existing validators that themselves work on individual
|
147
|
+
attribute values (including standard Rails validators, others that are part of
|
148
|
+
this gem, and likely many from other gems too).
|
149
|
+
|
150
|
+
By default it reports only one validation error per sub-validator, regardless
|
151
|
+
of how many keys fail validation. Use `multiple_errors: true` to report all
|
152
|
+
errors. See Array validator for more details.
|
153
|
+
|
154
|
+
validates :subjects,
|
155
|
+
hash_keys: {
|
156
|
+
format: /\A[a-z]+\z/,
|
157
|
+
# multiple_errors: true
|
158
|
+
}
|
159
|
+
|
160
|
+
|
161
|
+
## Hash Values validator ##
|
162
|
+
|
163
|
+
This is the companion to the Hash Keys validator and validates hash values
|
164
|
+
instead. It is conceptually the same as using the Array validator to validate
|
165
|
+
`hash_attribute.values`.
|
166
|
+
|
167
|
+
See Hash Keys validator for more details.
|
168
|
+
|
169
|
+
validates :subjects,
|
170
|
+
hash_values: {
|
171
|
+
length: 3..100,
|
172
|
+
# multiple_errors: true
|
173
|
+
}
|
174
|
+
|
175
|
+
|
138
176
|
## Hostname validator ##
|
139
177
|
|
140
178
|
Ensures an attribute is generally formatted as a hostname. It allows for any
|
@@ -217,7 +255,7 @@ Always skips over nil values; use `:presence` to validate those.
|
|
217
255
|
|
218
256
|
Ensures an attribute is generally formatted as a URL. If `addressable/uri` is
|
219
257
|
already loaded, it will be used to parse IDN's. Additionally, allowed schemes
|
220
|
-
can be specified; they default to ['http','https']
|
258
|
+
can be specified; they default to `['http','https']`.
|
221
259
|
|
222
260
|
validates :website, url: true
|
223
261
|
validates :secure_url, url: {scheme: 'https'}
|
data/lib/can_has_validations.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'active_model/validations'
|
2
2
|
|
3
|
-
%w(array email existence grandparent hostname ipaddr ordering url write_once).each do |validator|
|
3
|
+
%w(array email existence grandparent hash_keys hash_values hostname ipaddr ordering url write_once).each do |validator|
|
4
4
|
require "can_has_validations/validators/#{validator}_validator"
|
5
5
|
end
|
6
6
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
es:
|
2
|
+
errors:
|
3
|
+
messages:
|
4
|
+
invalid_email: "es un correo electrónico no válido"
|
5
|
+
invalid_hostname: "es un nombre de sistema no válido"
|
6
|
+
invalid_ip: "es una IP no válida"
|
7
|
+
ip_not_allowed: "no es una IP permitida"
|
8
|
+
single_ip_required: "debe ser solo una IP"
|
9
|
+
invalid_url: "es una URL no válida"
|
10
|
+
unchangeable: "no se puede cambiar"
|
11
|
+
before: "debe ser antes de %{attribute2}"
|
12
|
+
after: "debe ser después de %{attribute2}"
|
@@ -19,6 +19,18 @@
|
|
19
19
|
# multiple_errors: true,
|
20
20
|
# format: /\A[^aeiou]*\z/
|
21
21
|
# }
|
22
|
+
#
|
23
|
+
# the :if, :unless, and :on conditionals are not supported on sub-validators,
|
24
|
+
# but do work as normal on the :array validator itself.
|
25
|
+
#
|
26
|
+
# validates :permissions, if: :this_condition_works,
|
27
|
+
# array: {
|
28
|
+
# if: :this_condition_applies_to_permissions_but_not_each_element,
|
29
|
+
# inclusion: {
|
30
|
+
# in: %w(one two),
|
31
|
+
# unless: :conditions_on_subvalidators_are_ignored
|
32
|
+
# }
|
33
|
+
# }
|
22
34
|
|
23
35
|
module ActiveModel
|
24
36
|
module Validations
|
@@ -33,12 +45,17 @@ module ActiveModel
|
|
33
45
|
defaults = @options.dup
|
34
46
|
validations = defaults.slice!(*record_class.send(:_validates_default_keys), :attributes)
|
35
47
|
|
36
|
-
raise ArgumentError, "You need to supply at least one
|
48
|
+
raise ArgumentError, "You need to supply at least one validation for :#{kind}" if validations.empty?
|
37
49
|
|
38
50
|
defaults[:attributes] = attributes
|
39
51
|
|
40
52
|
@validators = validations.map do |key, sub_options|
|
41
53
|
next unless sub_options
|
54
|
+
|
55
|
+
if (cond_keys = _parse_validates_options(sub_options).keys & %i(if on unless)).any?
|
56
|
+
raise ArgumentError, ":#{kind} does not support conditionals on sub-validators - found on #{key}: #{cond_keys.map(&:inspect).join(', ')}"
|
57
|
+
end
|
58
|
+
|
42
59
|
key = "#{key.to_s.camelize}Validator"
|
43
60
|
|
44
61
|
begin
|
@@ -47,7 +64,7 @@ module ActiveModel
|
|
47
64
|
raise ArgumentError, "Unknown validator: '#{key}'"
|
48
65
|
end
|
49
66
|
|
50
|
-
klass.new(defaults.merge(_parse_validates_options(sub_options)))
|
67
|
+
klass.new(defaults.merge(_parse_validates_options(sub_options)).except(:if, :on, :unless))
|
51
68
|
end
|
52
69
|
end
|
53
70
|
|
@@ -56,7 +73,7 @@ module ActiveModel
|
|
56
73
|
error_count = count_errors(record)
|
57
74
|
|
58
75
|
Array(array_values).each do |value|
|
59
|
-
validator
|
76
|
+
validate_one(validator, record, attribute, value)
|
60
77
|
|
61
78
|
# to avoid repeating error messages, stop after a single error
|
62
79
|
unless validator.options[:multiple_errors]
|
@@ -66,6 +83,13 @@ module ActiveModel
|
|
66
83
|
end
|
67
84
|
end
|
68
85
|
|
86
|
+
def validate_one(validator, record, attribute, value)
|
87
|
+
unless validator.is_a?(ExistenceValidator)
|
88
|
+
return if (value.nil? && validator.options[:allow_nil]) || (value.blank? && validator.options[:allow_blank])
|
89
|
+
end
|
90
|
+
validator.validate_each(record, attribute, value)
|
91
|
+
end
|
92
|
+
|
69
93
|
|
70
94
|
private
|
71
95
|
|
@@ -73,6 +97,7 @@ module ActiveModel
|
|
73
97
|
record.errors.count
|
74
98
|
end
|
75
99
|
|
100
|
+
# copied from active_model/validations/validates.rb
|
76
101
|
def _parse_validates_options(options)
|
77
102
|
case options
|
78
103
|
when TrueClass
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# validates each key of a hash attribute
|
2
|
+
#
|
3
|
+
# by default only allows the first error per validator, regardless of how many
|
4
|
+
# keys fail validation. this improves performance and avoids a bunch of
|
5
|
+
# repeating error messages.
|
6
|
+
# use `multiple_errors: true` on :hash_keys or a single sub-validator to
|
7
|
+
# enable the full set of errors. this is potentially useful if each error
|
8
|
+
# message will vary based upon each hash key.
|
9
|
+
#
|
10
|
+
# the :if, :unless, and :on conditionals are not supported on sub-validators,
|
11
|
+
# but do work as normal on the :hash_keys validator itself.
|
12
|
+
#
|
13
|
+
# usage:
|
14
|
+
# validates :subjects,
|
15
|
+
# hash_keys: {
|
16
|
+
# format: /\A[a-z]+\z/,
|
17
|
+
# # multiple_errors: true
|
18
|
+
# }
|
19
|
+
|
20
|
+
module ActiveModel
|
21
|
+
module Validations
|
22
|
+
class HashKeysValidator < ArrayValidator
|
23
|
+
|
24
|
+
def validate_each(record, attribute, hash)
|
25
|
+
super(record, attribute, Hash(hash).keys)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# validates each value of a hash attribute
|
2
|
+
#
|
3
|
+
# by default only allows the first error per validator, regardless of how many
|
4
|
+
# values fail validation. this improves performance and avoids a bunch of
|
5
|
+
# repeating error messages.
|
6
|
+
# use `multiple_errors: true` on :hash_values or a single sub-validator to
|
7
|
+
# enable the full set of errors. this is potentially useful if each error
|
8
|
+
# message will vary based upon each hash value.
|
9
|
+
#
|
10
|
+
# the :if, :unless, and :on conditionals are not supported on sub-validators,
|
11
|
+
# but do work as normal on the :hash_values validator itself.
|
12
|
+
#
|
13
|
+
# usage:
|
14
|
+
# validates :subjects,
|
15
|
+
# hash_values: {
|
16
|
+
# length: 3..100,
|
17
|
+
# # multiple_errors: true
|
18
|
+
# }
|
19
|
+
|
20
|
+
module ActiveModel
|
21
|
+
module Validations
|
22
|
+
class HashValuesValidator < ArrayValidator
|
23
|
+
|
24
|
+
def initialize(options)
|
25
|
+
record_class = options[:class]
|
26
|
+
super
|
27
|
+
record_class.include HashValidatorKey
|
28
|
+
end
|
29
|
+
|
30
|
+
def validate_each(record, attribute, hash)
|
31
|
+
super(record, attribute, Array(Hash(hash)))
|
32
|
+
end
|
33
|
+
|
34
|
+
def validate_one(validator, record, attribute, key_and_value)
|
35
|
+
key, value = key_and_value
|
36
|
+
record.hash_validator_key = key
|
37
|
+
super(validator, record, attribute, value)
|
38
|
+
ensure
|
39
|
+
record.hash_validator_key = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
module HashValidatorKey
|
44
|
+
def hash_validator_key
|
45
|
+
@_hash_validator_key
|
46
|
+
end
|
47
|
+
|
48
|
+
def hash_validator_key=(v)
|
49
|
+
@_hash_validator_key = v
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: can_has_validations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- thomas morgan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-05-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -57,10 +57,13 @@ files:
|
|
57
57
|
- Rakefile
|
58
58
|
- lib/can_has_validations.rb
|
59
59
|
- lib/can_has_validations/locale/en.yml
|
60
|
+
- lib/can_has_validations/locale/es.yml
|
60
61
|
- lib/can_has_validations/validators/array_validator.rb
|
61
62
|
- lib/can_has_validations/validators/email_validator.rb
|
62
63
|
- lib/can_has_validations/validators/existence_validator.rb
|
63
64
|
- lib/can_has_validations/validators/grandparent_validator.rb
|
65
|
+
- lib/can_has_validations/validators/hash_keys_validator.rb
|
66
|
+
- lib/can_has_validations/validators/hash_values_validator.rb
|
64
67
|
- lib/can_has_validations/validators/hostname_validator.rb
|
65
68
|
- lib/can_has_validations/validators/ipaddr_validator.rb
|
66
69
|
- lib/can_has_validations/validators/ordering_validator.rb
|