active_storage_validations 0.8.1 → 0.8.2
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/README.md +3 -0
- data/lib/active_storage_validations/aspect_ratio_validator.rb +49 -116
- data/lib/active_storage_validations/content_type_validator.rb +8 -4
- data/lib/active_storage_validations/dimension_validator.rb +77 -177
- data/lib/active_storage_validations/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 813f828596f4fd712cff8e2f7f2b3fea5c668f03616bc3f621b8af742f7adff1
|
4
|
+
data.tar.gz: 57da59dd3aa086c343d51a191b2a4990100d2f4bd4c846d30ca9e41dafaa3ca9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 712ba73b0a9bfa737f09e003519aa9cbaa19dfdabd177ddcdefbff3f002a55f9758204808e0736136b61411b764eac922762cd6a90cd757f7cff610f6c560879
|
7
|
+
data.tar.gz: ddb33ce32755b8cac68fb2106fedd4a8a682d8c44edc6d639171a8e323fdd8c681b32d83336fcc807ecbc31a648b0a5304a996d1390f5d1e548c52caf9179b86
|
data/README.md
CHANGED
@@ -64,7 +64,10 @@ class User < ApplicationRecord
|
|
64
64
|
has_many_attached :photos
|
65
65
|
|
66
66
|
validates :avatar, attached: true, content_type: :png # Mime[:png].to_s => 'image/png'
|
67
|
+
# or
|
67
68
|
validates :photos, attached: true, content_type: [:png, :jpg, :jpeg]
|
69
|
+
# or
|
70
|
+
validates :avatar, content_type: /\Aimage\/.*\z/
|
68
71
|
end
|
69
72
|
```
|
70
73
|
|
@@ -2,24 +2,23 @@
|
|
2
2
|
|
3
3
|
require_relative 'metadata.rb'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
15
|
-
|
5
|
+
module ActiveStorageValidations
|
6
|
+
class AspectRatioValidator < ActiveModel::EachValidator # :nodoc
|
7
|
+
AVAILABLE_CHECKS = %i[with].freeze
|
8
|
+
PRECISION = 3
|
9
|
+
|
10
|
+
def initialize(options)
|
11
|
+
require 'mini_magick' unless defined?(MiniMagick)
|
12
|
+
super(options)
|
13
|
+
end
|
16
14
|
|
17
|
-
def check_validity!
|
18
|
-
return true if AVAILABLE_CHECKS.any? { |argument| options.key?(argument) }
|
19
|
-
raise ArgumentError, 'You must pass "aspect_ratio: :OPTION" option to the validator'
|
20
|
-
end
|
21
15
|
|
16
|
+
def check_validity!
|
17
|
+
return true if AVAILABLE_CHECKS.any? { |argument| options.key?(argument) }
|
18
|
+
raise ArgumentError, 'You must pass "aspect_ratio: :OPTION" option to the validator'
|
19
|
+
end
|
22
20
|
|
21
|
+
if Rails::VERSION::MAJOR >= 6
|
23
22
|
def validate_each(record, attribute, _value)
|
24
23
|
return true unless record.send(attribute).attached?
|
25
24
|
|
@@ -34,74 +33,8 @@ if Rails::VERSION::MAJOR >= 6
|
|
34
33
|
break
|
35
34
|
end
|
36
35
|
end
|
37
|
-
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
|
42
|
-
def is_valid?(record, attribute, metadata)
|
43
|
-
if metadata[:width].to_i <= 0 || metadata[:height].to_i <= 0
|
44
|
-
add_error(record, attribute, options[:message].presence || :image_metadata_missing)
|
45
|
-
return false
|
46
|
-
end
|
47
|
-
|
48
|
-
case options[:with]
|
49
|
-
when :square
|
50
|
-
return true if metadata[:width] == metadata[:height]
|
51
|
-
add_error(record, attribute, :aspect_ratio_not_square)
|
52
|
-
|
53
|
-
when :portrait
|
54
|
-
return true if metadata[:height] > metadata[:width]
|
55
|
-
add_error(record, attribute, :aspect_ratio_not_portrait)
|
56
|
-
|
57
|
-
when :landscape
|
58
|
-
return true if metadata[:width] > metadata[:height]
|
59
|
-
add_error(record, attribute, :aspect_ratio_not_landscape)
|
60
|
-
|
61
|
-
else
|
62
|
-
if options[:with] =~ /is\_(\d*)\_(\d*)/
|
63
|
-
x = $1.to_i
|
64
|
-
y = $2.to_i
|
65
|
-
|
66
|
-
return true if (x.to_f / y).round(PRECISION) == (metadata[:width].to_f / metadata[:height]).round(PRECISION)
|
67
|
-
|
68
|
-
add_error(record, attribute, :aspect_ratio_is_not, "#{x}x#{y}")
|
69
|
-
else
|
70
|
-
add_error(record, attribute, :aspect_ratio_unknown)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
false
|
74
|
-
end
|
75
|
-
|
76
|
-
|
77
|
-
def add_error(record, attribute, type, interpolate = options[:with])
|
78
|
-
key = options[:message].presence || type
|
79
|
-
return if record.errors.added?(attribute, key)
|
80
|
-
record.errors.add(attribute, key, aspect_ratio: interpolate)
|
81
|
-
end
|
82
|
-
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
else
|
87
|
-
# Rails 5
|
88
|
-
module ActiveStorageValidations
|
89
|
-
class AspectRatioValidator < ActiveModel::EachValidator # :nodoc
|
90
|
-
AVAILABLE_CHECKS = %i[with].freeze
|
91
|
-
PRECISION = 3
|
92
|
-
|
93
|
-
def initialize(options)
|
94
|
-
require 'mini_magick' unless defined?(MiniMagick)
|
95
|
-
super(options)
|
96
|
-
end
|
97
|
-
|
98
|
-
|
99
|
-
def check_validity!
|
100
|
-
return true if AVAILABLE_CHECKS.any? { |argument| options.key?(argument) }
|
101
|
-
raise ArgumentError, 'You must pass "aspect_ratio: :OPTION" option to the validator'
|
102
|
-
end
|
103
|
-
|
104
|
-
|
36
|
+
else
|
37
|
+
# Rails 5
|
105
38
|
def validate_each(record, attribute, _value)
|
106
39
|
return true unless record.send(attribute).attached?
|
107
40
|
|
@@ -116,52 +49,52 @@ else
|
|
116
49
|
break
|
117
50
|
end
|
118
51
|
end
|
52
|
+
end
|
119
53
|
|
120
54
|
|
121
|
-
|
55
|
+
private
|
122
56
|
|
123
57
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
58
|
+
def is_valid?(record, attribute, metadata)
|
59
|
+
if metadata[:width].to_i <= 0 || metadata[:height].to_i <= 0
|
60
|
+
add_error(record, attribute, options[:message].presence || :image_metadata_missing)
|
61
|
+
return false
|
62
|
+
end
|
129
63
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
64
|
+
case options[:with]
|
65
|
+
when :square
|
66
|
+
return true if metadata[:width] == metadata[:height]
|
67
|
+
add_error(record, attribute, :aspect_ratio_not_square)
|
134
68
|
|
135
|
-
|
136
|
-
|
137
|
-
|
69
|
+
when :portrait
|
70
|
+
return true if metadata[:height] > metadata[:width]
|
71
|
+
add_error(record, attribute, :aspect_ratio_not_portrait)
|
138
72
|
|
139
|
-
|
140
|
-
|
141
|
-
|
73
|
+
when :landscape
|
74
|
+
return true if metadata[:width] > metadata[:height]
|
75
|
+
add_error(record, attribute, :aspect_ratio_not_landscape)
|
142
76
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
77
|
+
else
|
78
|
+
if options[:with] =~ /is\_(\d*)\_(\d*)/
|
79
|
+
x = $1.to_i
|
80
|
+
y = $2.to_i
|
147
81
|
|
148
|
-
|
82
|
+
return true if (x.to_f / y).round(PRECISION) == (metadata[:width].to_f / metadata[:height]).round(PRECISION)
|
149
83
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
end
|
84
|
+
add_error(record, attribute, :aspect_ratio_is_not, "#{x}x#{y}")
|
85
|
+
else
|
86
|
+
add_error(record, attribute, :aspect_ratio_unknown)
|
154
87
|
end
|
155
|
-
false
|
156
88
|
end
|
89
|
+
false
|
90
|
+
end
|
157
91
|
|
158
92
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
end
|
164
|
-
|
93
|
+
def add_error(record, attribute, type, interpolate = options[:with])
|
94
|
+
key = options[:message].presence || type
|
95
|
+
return if record.errors.added?(attribute, key)
|
96
|
+
record.errors.add(attribute, key, aspect_ratio: interpolate)
|
165
97
|
end
|
98
|
+
|
166
99
|
end
|
167
|
-
end
|
100
|
+
end
|
@@ -11,7 +11,7 @@ module ActiveStorageValidations
|
|
11
11
|
errors_options[:message] = options[:message] if options[:message].present?
|
12
12
|
|
13
13
|
files.each do |file|
|
14
|
-
next if
|
14
|
+
next if is_valid?(file)
|
15
15
|
|
16
16
|
errors_options[:content_type] = content_type(file)
|
17
17
|
record.errors.add(attribute, :content_type_invalid, errors_options)
|
@@ -20,7 +20,7 @@ module ActiveStorageValidations
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def types
|
23
|
-
(Array.wrap(options[:with]) + Array.wrap(options[:in])).map do |type|
|
23
|
+
(Array.wrap(options[:with]) + Array.wrap(options[:in])).compact.map do |type|
|
24
24
|
Mime[type] || type
|
25
25
|
end
|
26
26
|
end
|
@@ -33,8 +33,12 @@ module ActiveStorageValidations
|
|
33
33
|
file.blob.present? && file.blob.content_type
|
34
34
|
end
|
35
35
|
|
36
|
-
def
|
37
|
-
|
36
|
+
def is_valid?(file)
|
37
|
+
if options[:with].is_a?(Regexp)
|
38
|
+
options[:with].match?(content_type(file).to_s)
|
39
|
+
else
|
40
|
+
content_type(file).in?(types)
|
41
|
+
end
|
38
42
|
end
|
39
43
|
end
|
40
44
|
end
|
@@ -2,39 +2,39 @@
|
|
2
2
|
|
3
3
|
require_relative 'metadata.rb'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
[
|
14
|
-
if
|
15
|
-
|
16
|
-
|
17
|
-
options[length][:min], options[length][:max] = range.min, range.max
|
18
|
-
end
|
5
|
+
module ActiveStorageValidations
|
6
|
+
class DimensionValidator < ActiveModel::EachValidator # :nodoc
|
7
|
+
AVAILABLE_CHECKS = %i[width height min max].freeze
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
require 'mini_magick' unless defined?(MiniMagick)
|
11
|
+
|
12
|
+
[:width, :height].each do |length|
|
13
|
+
if options[length] and options[length].is_a?(Hash)
|
14
|
+
if range = options[length][:in]
|
15
|
+
raise ArgumentError, ":in must be a Range" unless range.is_a?(Range)
|
16
|
+
options[length][:min], options[length][:max] = range.min, range.max
|
19
17
|
end
|
20
18
|
end
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
19
|
+
end
|
20
|
+
[:min, :max].each do |dim|
|
21
|
+
if range = options[dim]
|
22
|
+
raise ArgumentError, ":#{dim} must be a Range (width..height)" unless range.is_a?(Range)
|
23
|
+
options[:width] = { dim => range.first }
|
24
|
+
options[:height] = { dim => range.last }
|
27
25
|
end
|
28
|
-
super
|
29
26
|
end
|
27
|
+
super
|
28
|
+
end
|
30
29
|
|
31
30
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
def check_validity!
|
32
|
+
return true if AVAILABLE_CHECKS.any? { |argument| options.key?(argument) }
|
33
|
+
raise ArgumentError, 'You must pass either :width, :height, :min or :max to the validator'
|
34
|
+
end
|
36
35
|
|
37
36
|
|
37
|
+
if Rails::VERSION::MAJOR >= 6
|
38
38
|
def validate_each(record, attribute, _value)
|
39
39
|
return true unless record.send(attribute).attached?
|
40
40
|
|
@@ -48,107 +48,8 @@ if Rails::VERSION::MAJOR >= 6
|
|
48
48
|
break
|
49
49
|
end
|
50
50
|
end
|
51
|
-
|
52
|
-
|
53
|
-
def is_valid?(record, attribute, file_metadata)
|
54
|
-
# Validation fails unless file metadata contains valid width and height.
|
55
|
-
if file_metadata[:width].to_i <= 0 || file_metadata[:height].to_i <= 0
|
56
|
-
add_error(record, attribute, options[:message].presence || :image_metadata_missing)
|
57
|
-
return false
|
58
|
-
end
|
59
|
-
|
60
|
-
# Validation based on checks :min and :max (:min, :max has higher priority to :width, :height).
|
61
|
-
if options[:min] || options[:max]
|
62
|
-
if options[:min] && (
|
63
|
-
(options[:width][:min] && file_metadata[:width] < options[:width][:min]) ||
|
64
|
-
(options[:height][:min] && file_metadata[:height] < options[:height][:min])
|
65
|
-
)
|
66
|
-
add_error(record, attribute, options[:message].presence || :"dimension_min_inclusion", width: options[:width][:min], height: options[:height][:min])
|
67
|
-
return false
|
68
|
-
end
|
69
|
-
if options[:max] && (
|
70
|
-
(options[:width][:max] && file_metadata[:width] > options[:width][:max]) ||
|
71
|
-
(options[:height][:max] && file_metadata[:height] > options[:height][:max])
|
72
|
-
)
|
73
|
-
add_error(record, attribute, options[:message].presence || :"dimension_max_inclusion", width: options[:width][:max], height: options[:height][:max])
|
74
|
-
return false
|
75
|
-
end
|
76
|
-
|
77
|
-
# Validation based on checks :width and :height.
|
78
|
-
else
|
79
|
-
[:width, :height].each do |length|
|
80
|
-
next unless options[length]
|
81
|
-
if options[length].is_a?(Hash)
|
82
|
-
if options[length][:in] && (file_metadata[length] < options[length][:min] || file_metadata[length] > options[length][:max])
|
83
|
-
add_error(record, attribute, options[:message].presence || :"dimension_#{length}_inclusion", min: options[length][:min], max: options[length][:max])
|
84
|
-
return false
|
85
|
-
else
|
86
|
-
if options[length][:min] && file_metadata[length] < options[length][:min]
|
87
|
-
add_error(record, attribute, options[:message].presence || :"dimension_#{length}_greater_than_or_equal_to", length: options[length][:min])
|
88
|
-
return false
|
89
|
-
end
|
90
|
-
if options[length][:max] && file_metadata[length] > options[length][:max]
|
91
|
-
add_error(record, attribute, options[:message].presence || :"dimension_#{length}_less_than_or_equal_to", length: options[length][:max])
|
92
|
-
return false
|
93
|
-
end
|
94
|
-
end
|
95
|
-
else
|
96
|
-
if file_metadata[length] != options[length]
|
97
|
-
add_error(record, attribute, options[:message].presence || :"dimension_#{length}_equal_to", length: options[length])
|
98
|
-
return false
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
true # valid file
|
105
|
-
end
|
106
|
-
|
107
|
-
def add_error(record, attribute, type, *attrs)
|
108
|
-
key = options[:message].presence || type
|
109
|
-
return if record.errors.added?(attribute, key)
|
110
|
-
record.errors.add(attribute, key, *attrs)
|
111
|
-
end
|
112
|
-
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
else
|
119
|
-
# Rails 5
|
120
|
-
module ActiveStorageValidations
|
121
|
-
class DimensionValidator < ActiveModel::EachValidator # :nodoc
|
122
|
-
AVAILABLE_CHECKS = %i[width height min max].freeze
|
123
|
-
|
124
|
-
def initialize(options)
|
125
|
-
require 'mini_magick' unless defined?(MiniMagick)
|
126
|
-
|
127
|
-
[:width, :height].each do |length|
|
128
|
-
if options[length] and options[length].is_a?(Hash)
|
129
|
-
if range = options[length][:in]
|
130
|
-
raise ArgumentError, ":in must be a Range" unless range.is_a?(Range)
|
131
|
-
options[length][:min], options[length][:max] = range.min, range.max
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
[:min, :max].each do |dim|
|
136
|
-
if range = options[dim]
|
137
|
-
raise ArgumentError, ":#{dim} must be a Range (width..height)" unless range.is_a?(Range)
|
138
|
-
options[:width] = { dim => range.first }
|
139
|
-
options[:height] = { dim => range.last }
|
140
|
-
end
|
141
|
-
end
|
142
|
-
super
|
143
|
-
end
|
144
|
-
|
145
|
-
|
146
|
-
def check_validity!
|
147
|
-
return true if AVAILABLE_CHECKS.any? { |argument| options.key?(argument) }
|
148
|
-
raise ArgumentError, 'You must pass either :width, :height, :min or :max to the validator'
|
149
|
-
end
|
150
|
-
|
151
|
-
|
51
|
+
else
|
52
|
+
# Rails 5
|
152
53
|
def validate_each(record, attribute, _value)
|
153
54
|
return true unless record.send(attribute).attached?
|
154
55
|
|
@@ -161,69 +62,68 @@ else
|
|
161
62
|
break
|
162
63
|
end
|
163
64
|
end
|
65
|
+
end
|
66
|
+
|
164
67
|
|
68
|
+
def is_valid?(record, attribute, file_metadata)
|
69
|
+
# Validation fails unless file metadata contains valid width and height.
|
70
|
+
if file_metadata[:width].to_i <= 0 || file_metadata[:height].to_i <= 0
|
71
|
+
add_error(record, attribute, options[:message].presence || :image_metadata_missing)
|
72
|
+
return false
|
73
|
+
end
|
165
74
|
|
166
|
-
|
167
|
-
|
168
|
-
if
|
169
|
-
|
75
|
+
# Validation based on checks :min and :max (:min, :max has higher priority to :width, :height).
|
76
|
+
if options[:min] || options[:max]
|
77
|
+
if options[:min] && (
|
78
|
+
(options[:width][:min] && file_metadata[:width] < options[:width][:min]) ||
|
79
|
+
(options[:height][:min] && file_metadata[:height] < options[:height][:min])
|
80
|
+
)
|
81
|
+
add_error(record, attribute, options[:message].presence || :"dimension_min_inclusion", width: options[:width][:min], height: options[:height][:min])
|
82
|
+
return false
|
83
|
+
end
|
84
|
+
if options[:max] && (
|
85
|
+
(options[:width][:max] && file_metadata[:width] > options[:width][:max]) ||
|
86
|
+
(options[:height][:max] && file_metadata[:height] > options[:height][:max])
|
87
|
+
)
|
88
|
+
add_error(record, attribute, options[:message].presence || :"dimension_max_inclusion", width: options[:width][:max], height: options[:height][:max])
|
170
89
|
return false
|
171
90
|
end
|
172
91
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
)
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
(options[:height][:max] && file_metadata[:height] > options[:height][:max])
|
185
|
-
)
|
186
|
-
add_error(record, attribute, options[:message].presence || :"dimension_max_inclusion", width: options[:width][:max], height: options[:height][:max])
|
187
|
-
return false
|
188
|
-
end
|
189
|
-
|
190
|
-
# Validation based on checks :width and :height.
|
191
|
-
else
|
192
|
-
[:width, :height].each do |length|
|
193
|
-
next unless options[length]
|
194
|
-
if options[length].is_a?(Hash)
|
195
|
-
if options[length][:in] && (file_metadata[length] < options[length][:min] || file_metadata[length] > options[length][:max])
|
196
|
-
add_error(record, attribute, options[:message].presence || :"dimension_#{length}_inclusion", min: options[length][:min], max: options[length][:max])
|
92
|
+
# Validation based on checks :width and :height.
|
93
|
+
else
|
94
|
+
[:width, :height].each do |length|
|
95
|
+
next unless options[length]
|
96
|
+
if options[length].is_a?(Hash)
|
97
|
+
if options[length][:in] && (file_metadata[length] < options[length][:min] || file_metadata[length] > options[length][:max])
|
98
|
+
add_error(record, attribute, options[:message].presence || :"dimension_#{length}_inclusion", min: options[length][:min], max: options[length][:max])
|
99
|
+
return false
|
100
|
+
else
|
101
|
+
if options[length][:min] && file_metadata[length] < options[length][:min]
|
102
|
+
add_error(record, attribute, options[:message].presence || :"dimension_#{length}_greater_than_or_equal_to", length: options[length][:min])
|
197
103
|
return false
|
198
|
-
else
|
199
|
-
if options[length][:min] && file_metadata[length] < options[length][:min]
|
200
|
-
add_error(record, attribute, options[:message].presence || :"dimension_#{length}_greater_than_or_equal_to", length: options[length][:min])
|
201
|
-
return false
|
202
|
-
end
|
203
|
-
if options[length][:max] && file_metadata[length] > options[length][:max]
|
204
|
-
add_error(record, attribute, options[:message].presence || :"dimension_#{length}_less_than_or_equal_to", length: options[length][:max])
|
205
|
-
return false
|
206
|
-
end
|
207
104
|
end
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
return false
|
105
|
+
if options[length][:max] && file_metadata[length] > options[length][:max]
|
106
|
+
add_error(record, attribute, options[:message].presence || :"dimension_#{length}_less_than_or_equal_to", length: options[length][:max])
|
107
|
+
return false
|
212
108
|
end
|
213
109
|
end
|
110
|
+
else
|
111
|
+
if file_metadata[length] != options[length]
|
112
|
+
add_error(record, attribute, options[:message].presence || :"dimension_#{length}_equal_to", length: options[length])
|
113
|
+
return false
|
114
|
+
end
|
214
115
|
end
|
215
116
|
end
|
216
|
-
|
217
|
-
true # valid file
|
218
117
|
end
|
219
118
|
|
220
|
-
|
221
|
-
key = options[:message].presence || type
|
222
|
-
return if record.errors.added?(attribute, key)
|
223
|
-
record.errors.add(attribute, key, *attrs)
|
224
|
-
end
|
225
|
-
|
119
|
+
true # valid file
|
226
120
|
end
|
227
|
-
end
|
228
121
|
|
229
|
-
|
122
|
+
def add_error(record, attribute, type, *attrs)
|
123
|
+
key = options[:message].presence || type
|
124
|
+
return if record.errors.added?(attribute, key)
|
125
|
+
record.errors.add(attribute, key, *attrs)
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_storage_validations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Igor Kasyanchuk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-08-
|
11
|
+
date: 2019-08-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -137,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
139
|
requirements: []
|
140
|
-
rubygems_version: 3.0.
|
140
|
+
rubygems_version: 3.0.2
|
141
141
|
signing_key:
|
142
142
|
specification_version: 4
|
143
143
|
summary: Validations for Active Storage
|