active_storage_validations 1.1.4 → 1.3.0
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 +84 -33
- data/config/locales/da.yml +33 -0
- data/config/locales/de.yml +6 -0
- data/config/locales/en.yml +6 -0
- data/config/locales/es.yml +6 -0
- data/config/locales/fr.yml +6 -0
- data/config/locales/it.yml +6 -0
- data/config/locales/ja.yml +6 -0
- data/config/locales/nl.yml +6 -0
- data/config/locales/pl.yml +6 -0
- data/config/locales/pt-BR.yml +6 -0
- data/config/locales/ru.yml +6 -0
- data/config/locales/sv.yml +11 -1
- data/config/locales/tr.yml +6 -0
- data/config/locales/uk.yml +6 -0
- data/config/locales/vi.yml +6 -0
- data/config/locales/zh-CN.yml +6 -0
- data/lib/active_storage_validations/aspect_ratio_validator.rb +10 -34
- data/lib/active_storage_validations/attached_validator.rb +6 -4
- data/lib/active_storage_validations/base_size_validator.rb +68 -0
- data/lib/active_storage_validations/concerns/active_storageable.rb +28 -0
- data/lib/active_storage_validations/concerns/errorable.rb +4 -5
- data/lib/active_storage_validations/concerns/loggable.rb +9 -0
- data/lib/active_storage_validations/concerns/metadatable.rb +31 -0
- data/lib/active_storage_validations/content_type_spoof_detector.rb +130 -0
- data/lib/active_storage_validations/content_type_validator.rb +56 -22
- data/lib/active_storage_validations/dimension_validator.rb +31 -52
- data/lib/active_storage_validations/limit_validator.rb +5 -3
- data/lib/active_storage_validations/marcel_extensor.rb +5 -0
- data/lib/active_storage_validations/matchers/aspect_ratio_validator_matcher.rb +6 -15
- data/lib/active_storage_validations/matchers/attached_validator_matcher.rb +5 -13
- data/lib/active_storage_validations/matchers/base_size_validator_matcher.rb +134 -0
- data/lib/active_storage_validations/matchers/concerns/attachable.rb +66 -0
- data/lib/active_storage_validations/matchers/concerns/contextable.rb +20 -8
- data/lib/active_storage_validations/matchers/concerns/messageable.rb +1 -1
- data/lib/active_storage_validations/matchers/concerns/validatable.rb +9 -3
- data/lib/active_storage_validations/matchers/content_type_validator_matcher.rb +12 -2
- data/lib/active_storage_validations/matchers/dimension_validator_matcher.rb +6 -15
- data/lib/active_storage_validations/matchers/limit_validator_matcher.rb +127 -0
- data/lib/active_storage_validations/matchers/processable_image_validator_matcher.rb +78 -0
- data/lib/active_storage_validations/matchers/size_validator_matcher.rb +4 -139
- data/lib/active_storage_validations/matchers/total_size_validator_matcher.rb +31 -0
- data/lib/active_storage_validations/matchers.rb +6 -15
- data/lib/active_storage_validations/metadata.rb +27 -12
- data/lib/active_storage_validations/processable_image_validator.rb +17 -32
- data/lib/active_storage_validations/size_validator.rb +6 -55
- data/lib/active_storage_validations/total_size_validator.rb +45 -0
- data/lib/active_storage_validations/version.rb +1 -1
- data/lib/active_storage_validations.rb +4 -1
- metadata +45 -46
@@ -1,38 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
# https://github.com/thoughtbot/paperclip/blob/v6.1.0/lib/paperclip/matchers/validate_attachment_size_matcher.rb
|
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'
|
11
|
-
require_relative 'concerns/validatable.rb'
|
3
|
+
require_relative 'base_size_validator_matcher'
|
12
4
|
|
13
5
|
module ActiveStorageValidations
|
14
6
|
module Matchers
|
15
|
-
def validate_size_of(
|
16
|
-
SizeValidatorMatcher.new(
|
7
|
+
def validate_size_of(attribute_name)
|
8
|
+
SizeValidatorMatcher.new(attribute_name)
|
17
9
|
end
|
18
10
|
|
19
|
-
class SizeValidatorMatcher
|
20
|
-
include ActiveStorageable
|
21
|
-
include AllowBlankable
|
22
|
-
include Contextable
|
23
|
-
include Messageable
|
24
|
-
include Rspecable
|
25
|
-
include Validatable
|
26
|
-
|
27
|
-
def initialize(attribute_name)
|
28
|
-
initialize_allow_blankable
|
29
|
-
initialize_contextable
|
30
|
-
initialize_messageable
|
31
|
-
initialize_rspecable
|
32
|
-
@attribute_name = attribute_name
|
33
|
-
@min = @max = nil
|
34
|
-
end
|
35
|
-
|
11
|
+
class SizeValidatorMatcher < BaseSizeValidatorMatcher
|
36
12
|
def description
|
37
13
|
"validate file size of :#{@attribute_name}"
|
38
14
|
end
|
@@ -42,117 +18,6 @@ module ActiveStorageValidations
|
|
42
18
|
build_failure_message(message)
|
43
19
|
message.join("\n")
|
44
20
|
end
|
45
|
-
|
46
|
-
def less_than(size)
|
47
|
-
@max = size - 1.byte
|
48
|
-
self
|
49
|
-
end
|
50
|
-
|
51
|
-
def less_than_or_equal_to(size)
|
52
|
-
@max = size
|
53
|
-
self
|
54
|
-
end
|
55
|
-
|
56
|
-
def greater_than(size)
|
57
|
-
@min = size + 1.byte
|
58
|
-
self
|
59
|
-
end
|
60
|
-
|
61
|
-
def greater_than_or_equal_to(size)
|
62
|
-
@min = size
|
63
|
-
self
|
64
|
-
end
|
65
|
-
|
66
|
-
def between(range)
|
67
|
-
@min, @max = range.first, range.last
|
68
|
-
self
|
69
|
-
end
|
70
|
-
|
71
|
-
def matches?(subject)
|
72
|
-
@subject = subject.is_a?(Class) ? subject.new : subject
|
73
|
-
|
74
|
-
is_a_valid_active_storage_attribute? &&
|
75
|
-
is_context_valid? &&
|
76
|
-
is_allowing_blank? &&
|
77
|
-
is_custom_message_valid? &&
|
78
|
-
not_lower_than_min? &&
|
79
|
-
higher_than_min? &&
|
80
|
-
lower_than_max? &&
|
81
|
-
not_higher_than_max?
|
82
|
-
end
|
83
|
-
|
84
|
-
protected
|
85
|
-
|
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"
|
94
|
-
end
|
95
|
-
|
96
|
-
def not_lower_than_min?
|
97
|
-
@min.nil? || !passes_validation_with_size(@min - 1)
|
98
|
-
end
|
99
|
-
|
100
|
-
def higher_than_min?
|
101
|
-
@min.nil? || passes_validation_with_size(@min + 1)
|
102
|
-
end
|
103
|
-
|
104
|
-
def lower_than_max?
|
105
|
-
@max.nil? || @max == Float::INFINITY || passes_validation_with_size(@max - 1)
|
106
|
-
end
|
107
|
-
|
108
|
-
def not_higher_than_max?
|
109
|
-
@max.nil? || @max == Float::INFINITY || !passes_validation_with_size(@max + 1)
|
110
|
-
end
|
111
|
-
|
112
|
-
def passes_validation_with_size(size)
|
113
|
-
mock_size_for(io, size) do
|
114
|
-
attach_file
|
115
|
-
validate
|
116
|
-
is_valid? || add_failure_message_artefact(size)
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
def add_failure_message_artefact(size)
|
121
|
-
@failure_message_artefacts << { size: size }
|
122
|
-
false
|
123
|
-
end
|
124
|
-
|
125
|
-
def is_custom_message_valid?
|
126
|
-
return true unless @custom_message
|
127
|
-
|
128
|
-
mock_size_for(io, -1.kilobytes) do
|
129
|
-
attach_file
|
130
|
-
validate
|
131
|
-
has_an_error_message_which_is_custom_message?
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
def mock_size_for(io, size)
|
136
|
-
Matchers.stub_method(io, :size, size) do
|
137
|
-
yield
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
def attach_file
|
142
|
-
@subject.public_send(@attribute_name).attach(dummy_file)
|
143
|
-
end
|
144
|
-
|
145
|
-
def dummy_file
|
146
|
-
{
|
147
|
-
io: io,
|
148
|
-
filename: 'test.png',
|
149
|
-
content_type: 'image/png'
|
150
|
-
}
|
151
|
-
end
|
152
|
-
|
153
|
-
def io
|
154
|
-
@io ||= Tempfile.new('Hello world!')
|
155
|
-
end
|
156
21
|
end
|
157
22
|
end
|
158
23
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_size_validator_matcher'
|
4
|
+
|
5
|
+
module ActiveStorageValidations
|
6
|
+
module Matchers
|
7
|
+
def validate_total_size_of(attribute_name)
|
8
|
+
TotalSizeValidatorMatcher.new(attribute_name)
|
9
|
+
end
|
10
|
+
|
11
|
+
class TotalSizeValidatorMatcher < BaseSizeValidatorMatcher
|
12
|
+
def description
|
13
|
+
"validate total file size of :#{@attribute_name}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def failure_message
|
17
|
+
message = ["is expected to validate total file size of :#{@attribute_name}"]
|
18
|
+
build_failure_message(message)
|
19
|
+
message.join("\n")
|
20
|
+
end
|
21
|
+
|
22
|
+
protected
|
23
|
+
|
24
|
+
def attach_file
|
25
|
+
# has_many_attached relation
|
26
|
+
@subject.public_send(@attribute_name).attach([dummy_blob])
|
27
|
+
@subject.public_send(@attribute_name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -2,9 +2,12 @@
|
|
2
2
|
|
3
3
|
require 'active_storage_validations/matchers/aspect_ratio_validator_matcher'
|
4
4
|
require 'active_storage_validations/matchers/attached_validator_matcher'
|
5
|
+
require 'active_storage_validations/matchers/processable_image_validator_matcher'
|
6
|
+
require 'active_storage_validations/matchers/limit_validator_matcher'
|
5
7
|
require 'active_storage_validations/matchers/content_type_validator_matcher'
|
6
8
|
require 'active_storage_validations/matchers/dimension_validator_matcher'
|
7
9
|
require 'active_storage_validations/matchers/size_validator_matcher'
|
10
|
+
require 'active_storage_validations/matchers/total_size_validator_matcher'
|
8
11
|
|
9
12
|
module ActiveStorageValidations
|
10
13
|
module Matchers
|
@@ -23,21 +26,9 @@ module ActiveStorageValidations
|
|
23
26
|
end
|
24
27
|
|
25
28
|
def self.mock_metadata(attachment, width, height)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
stub_method(ActiveStorageValidations::Metadata, :new, mock) do
|
30
|
-
yield
|
31
|
-
end
|
32
|
-
else
|
33
|
-
# Stub the metadata analysis for rails 5
|
34
|
-
stub_method(attachment, :analyze, true) do
|
35
|
-
stub_method(attachment, :analyzed?, true) do
|
36
|
-
stub_method(attachment, :metadata, { width: width, height: height }) do
|
37
|
-
yield
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
29
|
+
mock = Struct.new(:metadata).new({ width: width, height: height })
|
30
|
+
stub_method(ActiveStorageValidations::Metadata, :new, mock) do
|
31
|
+
yield
|
41
32
|
end
|
42
33
|
end
|
43
34
|
end
|
@@ -1,5 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'concerns/loggable'
|
4
|
+
|
1
5
|
module ActiveStorageValidations
|
2
6
|
class Metadata
|
7
|
+
include Loggable
|
8
|
+
|
3
9
|
class InvalidImageError < StandardError; end
|
4
10
|
|
5
11
|
attr_reader :file
|
@@ -34,7 +40,7 @@ module ActiveStorageValidations
|
|
34
40
|
private
|
35
41
|
|
36
42
|
def image_processor
|
37
|
-
# Rails returns nil for default image processor, because it is set in an after
|
43
|
+
# Rails returns nil for default image processor, because it is set in an after initialize callback
|
38
44
|
# https://github.com/rails/rails/blob/89d8569abe2564c8187debf32dd3b4e33d6ad983/activestorage/lib/active_storage/engine.rb
|
39
45
|
Rails.application.config.active_storage.variant_processor || DEFAULT_IMAGE_PROCESSOR
|
40
46
|
end
|
@@ -62,11 +68,7 @@ module ActiveStorageValidations
|
|
62
68
|
if is_string || file.is_a?(ActiveStorage::Blob)
|
63
69
|
blob =
|
64
70
|
if is_string
|
65
|
-
|
66
|
-
ActiveStorage::Blob.find_signed(file)
|
67
|
-
else
|
68
|
-
ActiveStorage::Blob.find_signed!(file)
|
69
|
-
end
|
71
|
+
ActiveStorage::Blob.find_signed!(file)
|
70
72
|
else
|
71
73
|
file
|
72
74
|
end
|
@@ -101,7 +103,7 @@ module ActiveStorageValidations
|
|
101
103
|
end
|
102
104
|
|
103
105
|
def new_image_from_path(path)
|
104
|
-
if vips_image_processor? && (
|
106
|
+
if vips_image_processor? && (supported_vips_suffix?(path) || vips_version_below_8_8? || open_uri_tempfile?(path))
|
105
107
|
begin
|
106
108
|
Vips::Image.new_from_file(path)
|
107
109
|
rescue exception_class
|
@@ -116,6 +118,24 @@ module ActiveStorageValidations
|
|
116
118
|
end
|
117
119
|
end
|
118
120
|
|
121
|
+
def supported_vips_suffix?(path)
|
122
|
+
Vips::get_suffixes.include?(File.extname(path).downcase)
|
123
|
+
end
|
124
|
+
|
125
|
+
def vips_version_below_8_8?
|
126
|
+
# FYI, Vips 8.8 was released in 2019
|
127
|
+
# https://github.com/libvips/libvips/releases/tag/v8.8.0
|
128
|
+
!Vips::respond_to?(:vips_foreign_get_suffixes)
|
129
|
+
end
|
130
|
+
|
131
|
+
def open_uri_tempfile?(path)
|
132
|
+
# When trying to open urls for 'large' images, OpenURI will return a
|
133
|
+
# tempfile. That tempfile does not have an extension indicating the type
|
134
|
+
# of file. However, Vips will be able to process it anyway.
|
135
|
+
# The 'large' file value is derived from OpenUri::Buffer class (> 10ko)
|
136
|
+
path.split('/').last.starts_with?("open-uri")
|
137
|
+
end
|
138
|
+
|
119
139
|
def valid_image?(image)
|
120
140
|
return false unless image
|
121
141
|
|
@@ -156,10 +176,5 @@ module ActiveStorageValidations
|
|
156
176
|
raise "Something wrong with params."
|
157
177
|
end
|
158
178
|
end
|
159
|
-
|
160
|
-
def logger
|
161
|
-
Rails.logger
|
162
|
-
end
|
163
|
-
|
164
179
|
end
|
165
180
|
end
|
@@ -1,49 +1,34 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'concerns/active_storageable.rb'
|
3
4
|
require_relative 'concerns/errorable.rb'
|
5
|
+
require_relative 'concerns/metadatable.rb'
|
4
6
|
require_relative 'concerns/symbolizable.rb'
|
5
|
-
require_relative 'metadata.rb'
|
6
7
|
|
7
8
|
module ActiveStorageValidations
|
8
9
|
class ProcessableImageValidator < ActiveModel::EachValidator # :nodoc
|
9
|
-
include
|
10
|
+
include ActiveStorageable
|
10
11
|
include Errorable
|
12
|
+
include Metadatable
|
11
13
|
include Symbolizable
|
12
14
|
|
13
15
|
ERROR_TYPES = %i[
|
14
16
|
image_not_processable
|
15
17
|
].freeze
|
16
18
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
else
|
34
|
-
# Rails 5
|
35
|
-
def validate_each(record, attribute, _value)
|
36
|
-
return true unless record.send(attribute).attached?
|
37
|
-
|
38
|
-
files = Array.wrap(record.send(attribute))
|
39
|
-
|
40
|
-
files.each do |file|
|
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
|
45
|
-
end
|
46
|
-
end
|
19
|
+
def validate_each(record, attribute, _value)
|
20
|
+
return if no_attachments?(record, attribute)
|
21
|
+
|
22
|
+
validate_changed_files_from_metadata(record, attribute)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def is_valid?(record, attribute, attachable, metadata)
|
28
|
+
return if !metadata.empty?
|
29
|
+
|
30
|
+
errors_options = initialize_error_options(options, attachable)
|
31
|
+
add_error(record, attribute, ERROR_TYPES.first , **errors_options)
|
47
32
|
end
|
48
33
|
end
|
49
34
|
end
|
@@ -1,23 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
4
|
-
require_relative 'concerns/symbolizable.rb'
|
3
|
+
require_relative 'base_size_validator.rb'
|
5
4
|
|
6
5
|
module ActiveStorageValidations
|
7
|
-
class SizeValidator <
|
8
|
-
include OptionProcUnfolding
|
9
|
-
include Errorable
|
10
|
-
include Symbolizable
|
11
|
-
|
12
|
-
delegate :number_to_human_size, to: ActiveSupport::NumberHelper
|
13
|
-
|
14
|
-
AVAILABLE_CHECKS = %i[
|
15
|
-
less_than
|
16
|
-
less_than_or_equal_to
|
17
|
-
greater_than
|
18
|
-
greater_than_or_equal_to
|
19
|
-
between
|
20
|
-
].freeze
|
6
|
+
class SizeValidator < BaseSizeValidator
|
21
7
|
ERROR_TYPES = %i[
|
22
8
|
file_size_not_less_than
|
23
9
|
file_size_not_less_than_or_equal_to
|
@@ -26,58 +12,23 @@ module ActiveStorageValidations
|
|
26
12
|
file_size_not_between
|
27
13
|
].freeze
|
28
14
|
|
29
|
-
def check_validity!
|
30
|
-
unless AVAILABLE_CHECKS.one? { |argument| options.key?(argument) }
|
31
|
-
raise ArgumentError, 'You must pass either :less_than(_or_equal_to), :greater_than(_or_equal_to), or :between to the validator'
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
15
|
def validate_each(record, attribute, _value)
|
36
|
-
|
37
|
-
return true unless record.send(attribute).attached?
|
16
|
+
return if no_attachments?(record, attribute)
|
38
17
|
|
39
|
-
files = Array.wrap(record.send(attribute))
|
40
18
|
flat_options = unfold_procs(record, self.options, AVAILABLE_CHECKS)
|
41
19
|
|
42
|
-
|
20
|
+
attached_files(record, attribute).each do |file|
|
43
21
|
next if is_valid?(file.blob.byte_size, flat_options)
|
44
22
|
|
45
23
|
errors_options = initialize_error_options(options, file)
|
24
|
+
populate_error_options(errors_options, flat_options)
|
46
25
|
errors_options[:file_size] = number_to_human_size(file.blob.byte_size)
|
47
|
-
|
48
|
-
errors_options[:max_size] = number_to_human_size(max_size(flat_options))
|
26
|
+
|
49
27
|
keys = AVAILABLE_CHECKS & flat_options.keys
|
50
28
|
error_type = "file_size_not_#{keys.first}".to_sym
|
51
29
|
|
52
30
|
add_error(record, attribute, error_type, **errors_options)
|
53
|
-
break
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
|
59
|
-
def is_valid?(file_size, flat_options)
|
60
|
-
return false if file_size < 0
|
61
|
-
|
62
|
-
if flat_options[:between].present?
|
63
|
-
flat_options[:between].include?(file_size)
|
64
|
-
elsif flat_options[:less_than].present?
|
65
|
-
file_size < flat_options[:less_than]
|
66
|
-
elsif flat_options[:less_than_or_equal_to].present?
|
67
|
-
file_size <= flat_options[:less_than_or_equal_to]
|
68
|
-
elsif flat_options[:greater_than].present?
|
69
|
-
file_size > flat_options[:greater_than]
|
70
|
-
elsif flat_options[:greater_than_or_equal_to].present?
|
71
|
-
file_size >= flat_options[:greater_than_or_equal_to]
|
72
31
|
end
|
73
32
|
end
|
74
|
-
|
75
|
-
def min_size(flat_options)
|
76
|
-
flat_options[:between]&.min || flat_options[:greater_than] || flat_options[:greater_than_or_equal_to]
|
77
|
-
end
|
78
|
-
|
79
|
-
def max_size(flat_options)
|
80
|
-
flat_options[:between]&.max || flat_options[:less_than] || flat_options[:less_than_or_equal_to]
|
81
|
-
end
|
82
33
|
end
|
83
34
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_size_validator.rb'
|
4
|
+
|
5
|
+
module ActiveStorageValidations
|
6
|
+
class TotalSizeValidator < BaseSizeValidator
|
7
|
+
ERROR_TYPES = %i[
|
8
|
+
total_file_size_not_less_than
|
9
|
+
total_file_size_not_less_than_or_equal_to
|
10
|
+
total_file_size_not_greater_than
|
11
|
+
total_file_size_not_greater_than_or_equal_to
|
12
|
+
total_file_size_not_between
|
13
|
+
].freeze
|
14
|
+
|
15
|
+
def validate_each(record, attribute, _value)
|
16
|
+
custom_check_validity!(record, attribute)
|
17
|
+
|
18
|
+
return if no_attachments?(record, attribute)
|
19
|
+
|
20
|
+
total_file_size = attached_files(record, attribute).sum { |file| file.blob.byte_size }
|
21
|
+
flat_options = unfold_procs(record, self.options, AVAILABLE_CHECKS)
|
22
|
+
|
23
|
+
return if is_valid?(total_file_size, flat_options)
|
24
|
+
|
25
|
+
errors_options = initialize_error_options(options, nil)
|
26
|
+
populate_error_options(errors_options, flat_options)
|
27
|
+
errors_options[:total_file_size] = number_to_human_size(total_file_size)
|
28
|
+
|
29
|
+
keys = AVAILABLE_CHECKS & flat_options.keys
|
30
|
+
error_type = "total_file_size_not_#{keys.first}".to_sym
|
31
|
+
|
32
|
+
add_error(record, attribute, error_type, **errors_options)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def custom_check_validity!(record, attribute)
|
38
|
+
# We can't perform this check in the #check_validity! hook because we do not
|
39
|
+
# have enough data (only options & attributes are accessible)
|
40
|
+
unless record.send(attribute).is_a?(ActiveStorage::Attached::Many)
|
41
|
+
raise ArgumentError, 'This validator is only available for has_many_attached relations'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -8,11 +8,14 @@ require 'active_storage_validations/engine'
|
|
8
8
|
require 'active_storage_validations/option_proc_unfolding'
|
9
9
|
require 'active_storage_validations/attached_validator'
|
10
10
|
require 'active_storage_validations/content_type_validator'
|
11
|
-
require 'active_storage_validations/size_validator'
|
12
11
|
require 'active_storage_validations/limit_validator'
|
13
12
|
require 'active_storage_validations/dimension_validator'
|
14
13
|
require 'active_storage_validations/aspect_ratio_validator'
|
15
14
|
require 'active_storage_validations/processable_image_validator'
|
15
|
+
require 'active_storage_validations/size_validator'
|
16
|
+
require 'active_storage_validations/total_size_validator'
|
17
|
+
|
18
|
+
require 'active_storage_validations/marcel_extensor'
|
16
19
|
|
17
20
|
ActiveSupport.on_load(:active_record) do
|
18
21
|
send :include, ActiveStorageValidations
|