active_storage_validations 1.1.3 → 1.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +81 -55
- data/lib/active_storage_validations/aspect_ratio_validator.rb +47 -22
- data/lib/active_storage_validations/attached_validator.rb +12 -3
- data/lib/active_storage_validations/concerns/errorable.rb +38 -0
- data/lib/active_storage_validations/concerns/symbolizable.rb +8 -6
- data/lib/active_storage_validations/content_type_validator.rb +41 -6
- data/lib/active_storage_validations/dimension_validator.rb +15 -15
- data/lib/active_storage_validations/limit_validator.rb +44 -7
- data/lib/active_storage_validations/matchers/aspect_ratio_validator_matcher.rb +128 -0
- data/lib/active_storage_validations/matchers/attached_validator_matcher.rb +20 -23
- data/lib/active_storage_validations/matchers/concerns/active_storageable.rb +17 -0
- data/lib/active_storage_validations/matchers/concerns/allow_blankable.rb +26 -0
- data/lib/active_storage_validations/matchers/concerns/contextable.rb +35 -0
- data/lib/active_storage_validations/matchers/concerns/messageable.rb +26 -0
- data/lib/active_storage_validations/matchers/concerns/rspecable.rb +25 -0
- data/lib/active_storage_validations/matchers/concerns/validatable.rb +5 -10
- data/lib/active_storage_validations/matchers/content_type_validator_matcher.rb +39 -25
- data/lib/active_storage_validations/matchers/dimension_validator_matcher.rb +61 -44
- data/lib/active_storage_validations/matchers/size_validator_matcher.rb +41 -24
- data/lib/active_storage_validations/matchers.rb +1 -0
- data/lib/active_storage_validations/metadata.rb +42 -28
- data/lib/active_storage_validations/processable_image_validator.rb +14 -5
- data/lib/active_storage_validations/size_validator.rb +7 -6
- data/lib/active_storage_validations/version.rb +1 -1
- data/lib/active_storage_validations.rb +1 -1
- metadata +9 -3
- data/lib/active_storage_validations/error_handler.rb +0 -21
@@ -1,5 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'concerns/active_storageable.rb'
|
4
|
+
require_relative 'concerns/allow_blankable.rb'
|
5
|
+
require_relative 'concerns/contextable.rb'
|
6
|
+
require_relative 'concerns/messageable.rb'
|
7
|
+
require_relative 'concerns/rspecable.rb'
|
3
8
|
require_relative 'concerns/validatable.rb'
|
4
9
|
|
5
10
|
module ActiveStorageValidations
|
@@ -9,16 +14,35 @@ module ActiveStorageValidations
|
|
9
14
|
end
|
10
15
|
|
11
16
|
class DimensionValidatorMatcher
|
17
|
+
include ActiveStorageable
|
18
|
+
include AllowBlankable
|
19
|
+
include Contextable
|
20
|
+
include Messageable
|
21
|
+
include Rspecable
|
12
22
|
include Validatable
|
13
23
|
|
14
24
|
def initialize(attribute_name)
|
25
|
+
initialize_allow_blankable
|
26
|
+
initialize_contextable
|
27
|
+
initialize_messageable
|
28
|
+
initialize_rspecable
|
15
29
|
@attribute_name = attribute_name
|
16
30
|
@width_min = @width_max = @height_min = @height_max = nil
|
17
|
-
@custom_message = nil
|
18
31
|
end
|
19
32
|
|
20
33
|
def description
|
21
|
-
"validate image dimensions of
|
34
|
+
"validate the image dimensions of :#{@attribute_name}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def failure_message
|
38
|
+
message = ["is expected to validate dimensions of :#{@attribute_name}"]
|
39
|
+
build_failure_message(message)
|
40
|
+
message.join("\n")
|
41
|
+
end
|
42
|
+
|
43
|
+
def width(width)
|
44
|
+
@width_min = @width_max = width
|
45
|
+
self
|
22
46
|
end
|
23
47
|
|
24
48
|
def width_min(width)
|
@@ -31,13 +55,13 @@ module ActiveStorageValidations
|
|
31
55
|
self
|
32
56
|
end
|
33
57
|
|
34
|
-
def
|
35
|
-
@
|
58
|
+
def width_between(range)
|
59
|
+
@width_min, @width_max = range.first, range.last
|
36
60
|
self
|
37
61
|
end
|
38
62
|
|
39
|
-
def
|
40
|
-
@
|
63
|
+
def height(height)
|
64
|
+
@height_min = @height_max = height
|
41
65
|
self
|
42
66
|
end
|
43
67
|
|
@@ -51,25 +75,18 @@ module ActiveStorageValidations
|
|
51
75
|
self
|
52
76
|
end
|
53
77
|
|
54
|
-
def width_between(range)
|
55
|
-
@width_min, @width_max = range.first, range.last
|
56
|
-
self
|
57
|
-
end
|
58
|
-
|
59
78
|
def height_between(range)
|
60
79
|
@height_min, @height_max = range.first, range.last
|
61
80
|
self
|
62
81
|
end
|
63
82
|
|
64
|
-
def height(height)
|
65
|
-
@height_min = @height_max = height
|
66
|
-
self
|
67
|
-
end
|
68
|
-
|
69
83
|
def matches?(subject)
|
70
84
|
@subject = subject.is_a?(Class) ? subject.new : subject
|
71
85
|
|
72
|
-
|
86
|
+
is_a_valid_active_storage_attribute? &&
|
87
|
+
is_context_valid? &&
|
88
|
+
is_allowing_blank? &&
|
89
|
+
is_custom_message_valid? &&
|
73
90
|
width_not_smaller_than_min? &&
|
74
91
|
width_larger_than_min? &&
|
75
92
|
width_smaller_than_max? &&
|
@@ -79,24 +96,19 @@ module ActiveStorageValidations
|
|
79
96
|
height_larger_than_min? &&
|
80
97
|
height_smaller_than_max? &&
|
81
98
|
height_not_larger_than_max? &&
|
82
|
-
height_equals?
|
83
|
-
validate_custom_message?
|
84
|
-
end
|
85
|
-
|
86
|
-
def failure_message
|
87
|
-
<<~MESSAGE
|
88
|
-
is expected to validate dimensions of #{@attribute_name}
|
89
|
-
width between #{@width_min} and #{@width_max}
|
90
|
-
height between #{@height_min} and #{@height_max}
|
91
|
-
MESSAGE
|
99
|
+
height_equals?
|
92
100
|
end
|
93
101
|
|
94
102
|
protected
|
95
103
|
|
96
|
-
def
|
97
|
-
@
|
98
|
-
|
99
|
-
|
104
|
+
def build_failure_message(message)
|
105
|
+
return unless @failure_message_artefacts.present?
|
106
|
+
|
107
|
+
message << " but there seem to have issues with the matcher methods you used, since:"
|
108
|
+
@failure_message_artefacts.each do |error_case|
|
109
|
+
message << " validation failed when provided with a #{error_case[:width]}x#{error_case[:height]}px test image"
|
110
|
+
end
|
111
|
+
message << " whereas it should have passed"
|
100
112
|
end
|
101
113
|
|
102
114
|
def valid_width
|
@@ -108,53 +120,58 @@ module ActiveStorageValidations
|
|
108
120
|
end
|
109
121
|
|
110
122
|
def width_not_smaller_than_min?
|
111
|
-
@width_min.nil? || !passes_validation_with_dimensions(@width_min - 1, valid_height
|
123
|
+
@width_min.nil? || !passes_validation_with_dimensions(@width_min - 1, valid_height)
|
112
124
|
end
|
113
125
|
|
114
126
|
def width_larger_than_min?
|
115
|
-
@width_min.nil? || @width_min == @width_max || passes_validation_with_dimensions(@width_min + 1, valid_height
|
127
|
+
@width_min.nil? || @width_min == @width_max || passes_validation_with_dimensions(@width_min + 1, valid_height)
|
116
128
|
end
|
117
129
|
|
118
130
|
def width_smaller_than_max?
|
119
|
-
@width_max.nil? || @width_min == @width_max || passes_validation_with_dimensions(@width_max - 1, valid_height
|
131
|
+
@width_max.nil? || @width_min == @width_max || passes_validation_with_dimensions(@width_max - 1, valid_height)
|
120
132
|
end
|
121
133
|
|
122
134
|
def width_not_larger_than_max?
|
123
|
-
@width_max.nil? || !passes_validation_with_dimensions(@width_max + 1, valid_height
|
135
|
+
@width_max.nil? || !passes_validation_with_dimensions(@width_max + 1, valid_height)
|
124
136
|
end
|
125
137
|
|
126
138
|
def width_equals?
|
127
|
-
@width_min.nil? || @width_min != @width_max || passes_validation_with_dimensions(@width_min, valid_height
|
139
|
+
@width_min.nil? || @width_min != @width_max || passes_validation_with_dimensions(@width_min, valid_height)
|
128
140
|
end
|
129
141
|
|
130
142
|
def height_not_smaller_than_min?
|
131
|
-
@height_min.nil? || !passes_validation_with_dimensions(valid_width, @height_min - 1
|
143
|
+
@height_min.nil? || !passes_validation_with_dimensions(valid_width, @height_min - 1)
|
132
144
|
end
|
133
145
|
|
134
146
|
def height_larger_than_min?
|
135
|
-
@height_min.nil? || @height_min == @height_max || passes_validation_with_dimensions(valid_width, @height_min + 1
|
147
|
+
@height_min.nil? || @height_min == @height_max || passes_validation_with_dimensions(valid_width, @height_min + 1)
|
136
148
|
end
|
137
149
|
|
138
150
|
def height_smaller_than_max?
|
139
|
-
@height_max.nil? || @height_min == @height_max || passes_validation_with_dimensions(valid_width, @height_max - 1
|
151
|
+
@height_max.nil? || @height_min == @height_max || passes_validation_with_dimensions(valid_width, @height_max - 1)
|
140
152
|
end
|
141
153
|
|
142
154
|
def height_not_larger_than_max?
|
143
|
-
@height_max.nil? || !passes_validation_with_dimensions(valid_width, @height_max + 1
|
155
|
+
@height_max.nil? || !passes_validation_with_dimensions(valid_width, @height_max + 1)
|
144
156
|
end
|
145
157
|
|
146
158
|
def height_equals?
|
147
|
-
@height_min.nil? || @height_min != @height_max || passes_validation_with_dimensions(valid_width, @height_min
|
159
|
+
@height_min.nil? || @height_min != @height_max || passes_validation_with_dimensions(valid_width, @height_min)
|
148
160
|
end
|
149
161
|
|
150
|
-
def passes_validation_with_dimensions(width, height
|
162
|
+
def passes_validation_with_dimensions(width, height)
|
151
163
|
mock_dimensions_for(attach_file, width, height) do
|
152
164
|
validate
|
153
|
-
is_valid?
|
165
|
+
is_valid? || add_failure_message_artefact(width, height)
|
154
166
|
end
|
155
167
|
end
|
156
168
|
|
157
|
-
def
|
169
|
+
def add_failure_message_artefact(width, height)
|
170
|
+
@failure_message_artefacts << { width: width, height: height }
|
171
|
+
false
|
172
|
+
end
|
173
|
+
|
174
|
+
def is_custom_message_valid?
|
158
175
|
return true unless @custom_message
|
159
176
|
|
160
177
|
mock_dimensions_for(attach_file, -1, -1) do
|
@@ -3,6 +3,11 @@
|
|
3
3
|
# Big thank you to the paperclip validation matchers:
|
4
4
|
# https://github.com/thoughtbot/paperclip/blob/v6.1.0/lib/paperclip/matchers/validate_attachment_size_matcher.rb
|
5
5
|
|
6
|
+
require_relative 'concerns/active_storageable.rb'
|
7
|
+
require_relative 'concerns/allow_blankable.rb'
|
8
|
+
require_relative 'concerns/contextable.rb'
|
9
|
+
require_relative 'concerns/messageable.rb'
|
10
|
+
require_relative 'concerns/rspecable.rb'
|
6
11
|
require_relative 'concerns/validatable.rb'
|
7
12
|
|
8
13
|
module ActiveStorageValidations
|
@@ -12,16 +17,30 @@ module ActiveStorageValidations
|
|
12
17
|
end
|
13
18
|
|
14
19
|
class SizeValidatorMatcher
|
20
|
+
include ActiveStorageable
|
21
|
+
include AllowBlankable
|
22
|
+
include Contextable
|
23
|
+
include Messageable
|
24
|
+
include Rspecable
|
15
25
|
include Validatable
|
16
26
|
|
17
27
|
def initialize(attribute_name)
|
28
|
+
initialize_allow_blankable
|
29
|
+
initialize_contextable
|
30
|
+
initialize_messageable
|
31
|
+
initialize_rspecable
|
18
32
|
@attribute_name = attribute_name
|
19
33
|
@min = @max = nil
|
20
|
-
@custom_message = nil
|
21
34
|
end
|
22
35
|
|
23
36
|
def description
|
24
|
-
"validate file size of
|
37
|
+
"validate file size of :#{@attribute_name}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def failure_message
|
41
|
+
message = ["is expected to validate file size of :#{@attribute_name}"]
|
42
|
+
build_failure_message(message)
|
43
|
+
message.join("\n")
|
25
44
|
end
|
26
45
|
|
27
46
|
def less_than(size)
|
@@ -49,36 +68,29 @@ module ActiveStorageValidations
|
|
49
68
|
self
|
50
69
|
end
|
51
70
|
|
52
|
-
def with_message(message)
|
53
|
-
@custom_message = message
|
54
|
-
self
|
55
|
-
end
|
56
|
-
|
57
71
|
def matches?(subject)
|
58
72
|
@subject = subject.is_a?(Class) ? subject.new : subject
|
59
73
|
|
60
|
-
|
74
|
+
is_a_valid_active_storage_attribute? &&
|
75
|
+
is_context_valid? &&
|
76
|
+
is_allowing_blank? &&
|
77
|
+
is_custom_message_valid? &&
|
61
78
|
not_lower_than_min? &&
|
62
79
|
higher_than_min? &&
|
63
80
|
lower_than_max? &&
|
64
|
-
not_higher_than_max?
|
65
|
-
validate_custom_message?
|
66
|
-
end
|
67
|
-
|
68
|
-
def failure_message
|
69
|
-
"is expected to validate file size of #{@attribute_name} to be between #{@min} and #{@max} bytes"
|
70
|
-
end
|
71
|
-
|
72
|
-
def failure_message_when_negated
|
73
|
-
"is expected to not validate file size of #{@attribute_name} to be between #{@min} and #{@max} bytes"
|
81
|
+
not_higher_than_max?
|
74
82
|
end
|
75
83
|
|
76
84
|
protected
|
77
85
|
|
78
|
-
def
|
79
|
-
@
|
80
|
-
|
81
|
-
|
86
|
+
def build_failure_message(message)
|
87
|
+
return unless @failure_message_artefacts.present?
|
88
|
+
|
89
|
+
message << " but there seem to have issues with the matcher methods you used, since:"
|
90
|
+
@failure_message_artefacts.each do |error_case|
|
91
|
+
message << " validation failed when provided with a #{error_case[:size]} bytes test file"
|
92
|
+
end
|
93
|
+
message << " whereas it should have passed"
|
82
94
|
end
|
83
95
|
|
84
96
|
def not_lower_than_min?
|
@@ -101,11 +113,16 @@ module ActiveStorageValidations
|
|
101
113
|
mock_size_for(io, size) do
|
102
114
|
attach_file
|
103
115
|
validate
|
104
|
-
is_valid?
|
116
|
+
is_valid? || add_failure_message_artefact(size)
|
105
117
|
end
|
106
118
|
end
|
107
119
|
|
108
|
-
def
|
120
|
+
def add_failure_message_artefact(size)
|
121
|
+
@failure_message_artefacts << { size: size }
|
122
|
+
false
|
123
|
+
end
|
124
|
+
|
125
|
+
def is_custom_message_valid?
|
109
126
|
return true unless @custom_message
|
110
127
|
|
111
128
|
mock_size_for(io, -1.kilobytes) do
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'active_storage_validations/matchers/aspect_ratio_validator_matcher'
|
3
4
|
require 'active_storage_validations/matchers/attached_validator_matcher'
|
4
5
|
require 'active_storage_validations/matchers/content_type_validator_matcher'
|
5
6
|
require 'active_storage_validations/matchers/dimension_validator_matcher'
|
@@ -4,29 +4,18 @@ module ActiveStorageValidations
|
|
4
4
|
|
5
5
|
attr_reader :file
|
6
6
|
|
7
|
+
DEFAULT_IMAGE_PROCESSOR = :mini_magick.freeze
|
8
|
+
|
7
9
|
def initialize(file)
|
8
10
|
require_image_processor
|
9
11
|
@file = file
|
10
12
|
end
|
11
13
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
if image_processor == :vips && defined?(Vips)
|
18
|
-
Vips::Error
|
19
|
-
elsif defined?(MiniMagick)
|
20
|
-
MiniMagick::Error
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def require_image_processor
|
25
|
-
if image_processor == :vips
|
26
|
-
require 'vips' unless defined?(Vips)
|
27
|
-
else
|
28
|
-
require 'mini_magick' unless defined?(MiniMagick)
|
29
|
-
end
|
14
|
+
def valid?
|
15
|
+
read_image
|
16
|
+
true
|
17
|
+
rescue InvalidImageError
|
18
|
+
false
|
30
19
|
end
|
31
20
|
|
32
21
|
def metadata
|
@@ -42,14 +31,31 @@ module ActiveStorageValidations
|
|
42
31
|
{}
|
43
32
|
end
|
44
33
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
34
|
+
private
|
35
|
+
|
36
|
+
def image_processor
|
37
|
+
# Rails returns nil for default image processor, because it is set in an after initiliaze callback
|
38
|
+
# https://github.com/rails/rails/blob/89d8569abe2564c8187debf32dd3b4e33d6ad983/activestorage/lib/active_storage/engine.rb
|
39
|
+
Rails.application.config.active_storage.variant_processor || DEFAULT_IMAGE_PROCESSOR
|
50
40
|
end
|
51
41
|
|
52
|
-
|
42
|
+
def require_image_processor
|
43
|
+
case image_processor
|
44
|
+
when :vips then require 'vips' unless defined?(Vips)
|
45
|
+
when :mini_magick then require 'mini_magick' unless defined?(MiniMagick)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def exception_class
|
50
|
+
case image_processor
|
51
|
+
when :vips then Vips::Error
|
52
|
+
when :mini_magick then MiniMagick::Error
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def vips_image_processor?
|
57
|
+
image_processor == :vips
|
58
|
+
end
|
53
59
|
|
54
60
|
def read_image
|
55
61
|
is_string = file.is_a?(String)
|
@@ -95,8 +101,16 @@ module ActiveStorageValidations
|
|
95
101
|
end
|
96
102
|
|
97
103
|
def new_image_from_path(path)
|
98
|
-
if
|
99
|
-
|
104
|
+
if vips_image_processor? && (Vips::get_suffixes.include?(File.extname(path).downcase) || !Vips::respond_to?(:vips_foreign_get_suffixes))
|
105
|
+
begin
|
106
|
+
Vips::Image.new_from_file(path)
|
107
|
+
rescue exception_class
|
108
|
+
# We handle cases where an error is raised when reading the file
|
109
|
+
# because Vips can throw errors rather than returning false
|
110
|
+
# We stumble upon this issue while reading 0 byte size file
|
111
|
+
# https://github.com/janko/image_processing/issues/97
|
112
|
+
false
|
113
|
+
end
|
100
114
|
elsif defined?(MiniMagick)
|
101
115
|
MiniMagick::Image.new(path)
|
102
116
|
end
|
@@ -105,13 +119,13 @@ module ActiveStorageValidations
|
|
105
119
|
def valid_image?(image)
|
106
120
|
return false unless image
|
107
121
|
|
108
|
-
|
122
|
+
vips_image_processor? && image.is_a?(Vips::Image) ? image.avg : image.valid?
|
109
123
|
rescue exception_class
|
110
124
|
false
|
111
125
|
end
|
112
126
|
|
113
127
|
def rotated_image?(image)
|
114
|
-
if
|
128
|
+
if vips_image_processor? && image.is_a?(Vips::Image)
|
115
129
|
image.get('exif-ifd0-Orientation').include?('Right-top') ||
|
116
130
|
image.get('exif-ifd0-Orientation').include?('Left-bottom')
|
117
131
|
else
|
@@ -1,27 +1,33 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'concerns/errorable.rb'
|
3
4
|
require_relative 'concerns/symbolizable.rb'
|
4
5
|
require_relative 'metadata.rb'
|
5
6
|
|
6
7
|
module ActiveStorageValidations
|
7
8
|
class ProcessableImageValidator < ActiveModel::EachValidator # :nodoc
|
8
9
|
include OptionProcUnfolding
|
9
|
-
include
|
10
|
+
include Errorable
|
10
11
|
include Symbolizable
|
11
12
|
|
13
|
+
ERROR_TYPES = %i[
|
14
|
+
image_not_processable
|
15
|
+
].freeze
|
16
|
+
|
12
17
|
if Rails.gem_version >= Gem::Version.new('6.0.0')
|
13
18
|
def validate_each(record, attribute, _value)
|
14
19
|
return true unless record.send(attribute).attached?
|
15
20
|
|
16
|
-
errors_options = initialize_error_options(options)
|
17
|
-
|
18
21
|
changes = record.attachment_changes[attribute.to_s]
|
19
22
|
return true if changes.blank?
|
20
23
|
|
21
24
|
files = Array.wrap(changes.is_a?(ActiveStorage::Attached::Changes::CreateMany) ? changes.attachables : changes.attachable)
|
22
25
|
|
23
26
|
files.each do |file|
|
24
|
-
|
27
|
+
if !Metadata.new(file).valid?
|
28
|
+
errors_options = initialize_error_options(options, file)
|
29
|
+
add_error(record, attribute, ERROR_TYPES.first , **errors_options) unless Metadata.new(file).valid?
|
30
|
+
end
|
25
31
|
end
|
26
32
|
end
|
27
33
|
else
|
@@ -32,7 +38,10 @@ module ActiveStorageValidations
|
|
32
38
|
files = Array.wrap(record.send(attribute))
|
33
39
|
|
34
40
|
files.each do |file|
|
35
|
-
|
41
|
+
if !Metadata.new(file).valid?
|
42
|
+
errors_options = initialize_error_options(options, file)
|
43
|
+
add_error(record, attribute, ERROR_TYPES.first , **errors_options) unless Metadata.new(file).valid?
|
44
|
+
end
|
36
45
|
end
|
37
46
|
end
|
38
47
|
end
|
@@ -1,11 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'concerns/errorable.rb'
|
3
4
|
require_relative 'concerns/symbolizable.rb'
|
4
5
|
|
5
6
|
module ActiveStorageValidations
|
6
7
|
class SizeValidator < ActiveModel::EachValidator # :nodoc:
|
7
8
|
include OptionProcUnfolding
|
8
|
-
include
|
9
|
+
include Errorable
|
9
10
|
include Symbolizable
|
10
11
|
|
11
12
|
delegate :number_to_human_size, to: ActiveSupport::NumberHelper
|
@@ -36,14 +37,12 @@ module ActiveStorageValidations
|
|
36
37
|
return true unless record.send(attribute).attached?
|
37
38
|
|
38
39
|
files = Array.wrap(record.send(attribute))
|
39
|
-
|
40
|
-
errors_options = initialize_error_options(options)
|
41
|
-
|
42
40
|
flat_options = unfold_procs(record, self.options, AVAILABLE_CHECKS)
|
43
41
|
|
44
42
|
files.each do |file|
|
45
|
-
next if
|
43
|
+
next if is_valid?(file.blob.byte_size, flat_options)
|
46
44
|
|
45
|
+
errors_options = initialize_error_options(options, file)
|
47
46
|
errors_options[:file_size] = number_to_human_size(file.blob.byte_size)
|
48
47
|
errors_options[:min_size] = number_to_human_size(min_size(flat_options))
|
49
48
|
errors_options[:max_size] = number_to_human_size(max_size(flat_options))
|
@@ -55,7 +54,9 @@ module ActiveStorageValidations
|
|
55
54
|
end
|
56
55
|
end
|
57
56
|
|
58
|
-
|
57
|
+
private
|
58
|
+
|
59
|
+
def is_valid?(file_size, flat_options)
|
59
60
|
return false if file_size < 0
|
60
61
|
|
61
62
|
if flat_options[:between].present?
|
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'active_model'
|
4
|
+
require 'active_support/concern'
|
4
5
|
|
5
6
|
require 'active_storage_validations/railtie'
|
6
7
|
require 'active_storage_validations/engine'
|
7
8
|
require 'active_storage_validations/option_proc_unfolding'
|
8
|
-
require 'active_storage_validations/error_handler'
|
9
9
|
require 'active_storage_validations/attached_validator'
|
10
10
|
require 'active_storage_validations/content_type_validator'
|
11
11
|
require 'active_storage_validations/size_validator'
|
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: 1.1.
|
4
|
+
version: 1.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Igor Kasyanchuk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|
@@ -234,14 +234,20 @@ files:
|
|
234
234
|
- lib/active_storage_validations.rb
|
235
235
|
- lib/active_storage_validations/aspect_ratio_validator.rb
|
236
236
|
- lib/active_storage_validations/attached_validator.rb
|
237
|
+
- lib/active_storage_validations/concerns/errorable.rb
|
237
238
|
- lib/active_storage_validations/concerns/symbolizable.rb
|
238
239
|
- lib/active_storage_validations/content_type_validator.rb
|
239
240
|
- lib/active_storage_validations/dimension_validator.rb
|
240
241
|
- lib/active_storage_validations/engine.rb
|
241
|
-
- lib/active_storage_validations/error_handler.rb
|
242
242
|
- lib/active_storage_validations/limit_validator.rb
|
243
243
|
- lib/active_storage_validations/matchers.rb
|
244
|
+
- lib/active_storage_validations/matchers/aspect_ratio_validator_matcher.rb
|
244
245
|
- lib/active_storage_validations/matchers/attached_validator_matcher.rb
|
246
|
+
- lib/active_storage_validations/matchers/concerns/active_storageable.rb
|
247
|
+
- lib/active_storage_validations/matchers/concerns/allow_blankable.rb
|
248
|
+
- lib/active_storage_validations/matchers/concerns/contextable.rb
|
249
|
+
- lib/active_storage_validations/matchers/concerns/messageable.rb
|
250
|
+
- lib/active_storage_validations/matchers/concerns/rspecable.rb
|
245
251
|
- lib/active_storage_validations/matchers/concerns/validatable.rb
|
246
252
|
- lib/active_storage_validations/matchers/content_type_validator_matcher.rb
|
247
253
|
- lib/active_storage_validations/matchers/dimension_validator_matcher.rb
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module ActiveStorageValidations
|
2
|
-
module ErrorHandler
|
3
|
-
|
4
|
-
def initialize_error_options(options)
|
5
|
-
{
|
6
|
-
validator_type: self.class.to_sym,
|
7
|
-
custom_message: (options[:message] if options[:message].present?)
|
8
|
-
}.compact
|
9
|
-
end
|
10
|
-
|
11
|
-
def add_error(record, attribute, error_type, **errors_options)
|
12
|
-
type = errors_options[:custom_message].presence || error_type
|
13
|
-
return if record.errors.added?(attribute, type)
|
14
|
-
|
15
|
-
# You can read https://api.rubyonrails.org/classes/ActiveModel/Errors.html#method-i-add
|
16
|
-
# to better understand how Rails model errors work
|
17
|
-
record.errors.add(attribute, type, **errors_options)
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
21
|
-
end
|