active_storage_validations 0.9.8 → 1.0.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 +20 -3
- data/config/locales/zh-CN.yml +22 -0
- data/lib/active_storage_validations/aspect_ratio_validator.rb +15 -17
- data/lib/active_storage_validations/content_type_validator.rb +15 -9
- data/lib/active_storage_validations/dimension_validator.rb +38 -32
- data/lib/active_storage_validations/limit_validator.rb +12 -10
- data/lib/active_storage_validations/option_proc_unfolding.rb +16 -0
- data/lib/active_storage_validations/size_validator.rb +22 -20
- data/lib/active_storage_validations/version.rb +1 -1
- data/lib/active_storage_validations.rb +1 -0
- metadata +19 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c3fa76d4dc0cf3d5bffc62dcc604d6f38edf165931c94d9314288606b6205a56
|
4
|
+
data.tar.gz: 9adb8defb7d44c65a4ea67cf632087d423a1c2c44b918822653638132f8beef4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a2d4ce5113ed8a018d71b4d40b01c11946892eea438d2b7481b7007511022695998271d06215e6ddf07929d4e057fc8411a2b0babcb508f70af6140fb4d65c8
|
7
|
+
data.tar.gz: 3d31b7848f3174a8df330e5410b5c1aec018a243bfdefa2abdfc8eee9d9f652e34645853da38dee2b1627ef42efa679fabdac11e896a6a37ce9cd0ed1c5569f7
|
data/README.md
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
[<img src="https://github.com/igorkasyanchuk/rails_time_travel/blob/main/docs/more_gems.png?raw=true"
|
2
|
+
/>](https://www.railsjazz.com/?utm_source=github&utm_medium=top&utm_campaign=active_storage_validations)
|
3
|
+
|
1
4
|
# Active Storage Validations
|
2
5
|
|
3
6
|
[](https://github.com/igorkasyanchuk/active_storage_validations/actions)
|
@@ -17,6 +20,7 @@ This gems doing it for you. Just use `attached: true` or `content_type: 'image/p
|
|
17
20
|
* validates number of uploaded files (min/max required)
|
18
21
|
* validates aspect ratio (if square, portrait, landscape, is_16_9, ...)
|
19
22
|
* custom error messages
|
23
|
+
* allow procs for dynamic determination of values
|
20
24
|
|
21
25
|
## Usage
|
22
26
|
|
@@ -121,6 +125,18 @@ class User < ApplicationRecord
|
|
121
125
|
end
|
122
126
|
```
|
123
127
|
|
128
|
+
- Proc Usage:
|
129
|
+
|
130
|
+
Procs can be used instead of values in all the above examples. They will be called on every validation.
|
131
|
+
```ruby
|
132
|
+
class User < ApplicationRecord
|
133
|
+
has_many_attached :proc_files
|
134
|
+
|
135
|
+
validates :proc_files, limit: { max: -> (record) { record.admin? ? 100 : 10 } }
|
136
|
+
end
|
137
|
+
|
138
|
+
```
|
139
|
+
|
124
140
|
## Internationalization (I18n)
|
125
141
|
|
126
142
|
Active Storage Validations uses I18n for error messages. For this, add these keys in your translation file:
|
@@ -303,12 +319,10 @@ To run tests in root folder of gem:
|
|
303
319
|
Snippet to run in console:
|
304
320
|
|
305
321
|
```
|
306
|
-
BUNDLE_GEMFILE=gemfiles/rails_5_2.gemfile bundle
|
307
322
|
BUNDLE_GEMFILE=gemfiles/rails_6_0.gemfile bundle
|
308
323
|
BUNDLE_GEMFILE=gemfiles/rails_6_1.gemfile bundle
|
309
324
|
BUNDLE_GEMFILE=gemfiles/rails_7_0.gemfile bundle
|
310
325
|
BUNDLE_GEMFILE=gemfiles/rails_next.gemfile bundle
|
311
|
-
BUNDLE_GEMFILE=gemfiles/rails_5_2.gemfile bundle exec rake test
|
312
326
|
BUNDLE_GEMFILE=gemfiles/rails_6_0.gemfile bundle exec rake test
|
313
327
|
BUNDLE_GEMFILE=gemfiles/rails_6_1.gemfile bundle exec rake test
|
314
328
|
BUNDLE_GEMFILE=gemfiles/rails_7_0.gemfile bundle exec rake test
|
@@ -378,10 +392,13 @@ You are welcome to contribute.
|
|
378
392
|
- https://github.com/stephensolis
|
379
393
|
- https://github.com/kwent
|
380
394
|
= https://github.com/Animesh-Ghosh
|
395
|
+
= https://github.com/gr8bit
|
396
|
+
= https://github.com/codegeek319
|
397
|
+
= https://github.com/clwy-cn
|
381
398
|
|
382
399
|
## License
|
383
400
|
|
384
401
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
385
402
|
|
386
403
|
[<img src="https://github.com/igorkasyanchuk/rails_time_travel/blob/main/docs/more_gems.png?raw=true"
|
387
|
-
/>](https://www.railsjazz.com
|
404
|
+
/>](https://www.railsjazz.com/?utm_source=github&utm_medium=bottom&utm_campaign=active_storage_validations)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
zh-CN:
|
2
|
+
errors:
|
3
|
+
messages:
|
4
|
+
content_type_invalid: "文件类型错误"
|
5
|
+
file_size_out_of_range: "文件大小 %{file_size} 超出限定范围"
|
6
|
+
limit_out_of_range: "文件数超出限定范围"
|
7
|
+
image_metadata_missing: "不是有效的图像"
|
8
|
+
dimension_min_inclusion: "必须大于或等于 %{width} x %{height} 像素"
|
9
|
+
dimension_max_inclusion: "必须小于或等于 %{width} x %{height} 像素"
|
10
|
+
dimension_width_inclusion: "宽度不在 %{min} 和 %{max} 像素之间"
|
11
|
+
dimension_height_inclusion: "高度不在 %{min} 和 %{max} 像素之间"
|
12
|
+
dimension_width_greater_than_or_equal_to: "宽度必须大于或等于 %{length} 像素"
|
13
|
+
dimension_height_greater_than_or_equal_to: "高度必须大于或等于 %{length} 像素"
|
14
|
+
dimension_width_less_than_or_equal_to: "宽度必须小于或等于 %{length} 像素"
|
15
|
+
dimension_height_less_than_or_equal_to: "高度必须小于或等于 %{length} 像素"
|
16
|
+
dimension_width_equal_to: "宽度必须等于 %{length} 像素"
|
17
|
+
dimension_height_equal_to: "高度必须等于 %{length} 像素"
|
18
|
+
aspect_ratio_not_square: "必须是方形图片"
|
19
|
+
aspect_ratio_not_portrait: "必须是竖屏图片"
|
20
|
+
aspect_ratio_not_landscape: "必须是横屏图片"
|
21
|
+
aspect_ratio_is_not: "纵横比必须是 %{aspect_ratio}"
|
22
|
+
aspect_ratio_unknown: "未知的纵横比"
|
@@ -4,17 +4,14 @@ require_relative 'metadata.rb'
|
|
4
4
|
|
5
5
|
module ActiveStorageValidations
|
6
6
|
class AspectRatioValidator < ActiveModel::EachValidator # :nodoc
|
7
|
+
include OptionProcUnfolding
|
8
|
+
|
7
9
|
AVAILABLE_CHECKS = %i[with].freeze
|
8
10
|
PRECISION = 3
|
9
11
|
|
10
|
-
def initialize(options)
|
11
|
-
super(options)
|
12
|
-
end
|
13
|
-
|
14
|
-
|
15
12
|
def check_validity!
|
16
13
|
return true if AVAILABLE_CHECKS.any? { |argument| options.key?(argument) }
|
17
|
-
raise ArgumentError, 'You must pass
|
14
|
+
raise ArgumentError, 'You must pass :with to the validator'
|
18
15
|
end
|
19
16
|
|
20
17
|
if Rails.gem_version >= Gem::Version.new('6.0.0')
|
@@ -55,26 +52,27 @@ module ActiveStorageValidations
|
|
55
52
|
|
56
53
|
|
57
54
|
def is_valid?(record, attribute, metadata)
|
55
|
+
flat_options = unfold_procs(record, self.options, AVAILABLE_CHECKS)
|
58
56
|
if metadata[:width].to_i <= 0 || metadata[:height].to_i <= 0
|
59
|
-
add_error(record, attribute,
|
57
|
+
add_error(record, attribute, :image_metadata_missing, flat_options[:with])
|
60
58
|
return false
|
61
59
|
end
|
62
60
|
|
63
|
-
case
|
61
|
+
case flat_options[:with]
|
64
62
|
when :square
|
65
63
|
return true if metadata[:width] == metadata[:height]
|
66
|
-
add_error(record, attribute, :aspect_ratio_not_square)
|
64
|
+
add_error(record, attribute, :aspect_ratio_not_square, flat_options[:with])
|
67
65
|
|
68
66
|
when :portrait
|
69
67
|
return true if metadata[:height] > metadata[:width]
|
70
|
-
add_error(record, attribute, :aspect_ratio_not_portrait)
|
68
|
+
add_error(record, attribute, :aspect_ratio_not_portrait, flat_options[:with])
|
71
69
|
|
72
70
|
when :landscape
|
73
71
|
return true if metadata[:width] > metadata[:height]
|
74
|
-
add_error(record, attribute, :aspect_ratio_not_landscape)
|
72
|
+
add_error(record, attribute, :aspect_ratio_not_landscape, flat_options[:with])
|
75
73
|
|
76
74
|
else
|
77
|
-
if
|
75
|
+
if flat_options[:with] =~ /is_(\d*)_(\d*)/
|
78
76
|
x = $1.to_i
|
79
77
|
y = $2.to_i
|
80
78
|
|
@@ -82,17 +80,17 @@ module ActiveStorageValidations
|
|
82
80
|
|
83
81
|
add_error(record, attribute, :aspect_ratio_is_not, "#{x}x#{y}")
|
84
82
|
else
|
85
|
-
add_error(record, attribute, :aspect_ratio_unknown)
|
83
|
+
add_error(record, attribute, :aspect_ratio_unknown, flat_options[:with])
|
86
84
|
end
|
87
85
|
end
|
88
86
|
false
|
89
87
|
end
|
90
88
|
|
91
89
|
|
92
|
-
def add_error(record, attribute,
|
93
|
-
|
94
|
-
return if record.errors.added?(attribute,
|
95
|
-
record.errors.add(attribute,
|
90
|
+
def add_error(record, attribute, default_message, interpolate)
|
91
|
+
message = options[:message].presence || default_message
|
92
|
+
return if record.errors.added?(attribute, message)
|
93
|
+
record.errors.add(attribute, message, aspect_ratio: interpolate)
|
96
94
|
end
|
97
95
|
|
98
96
|
end
|
@@ -2,16 +2,23 @@
|
|
2
2
|
|
3
3
|
module ActiveStorageValidations
|
4
4
|
class ContentTypeValidator < ActiveModel::EachValidator # :nodoc:
|
5
|
+
include OptionProcUnfolding
|
6
|
+
|
7
|
+
AVAILABLE_CHECKS = %i[with in].freeze
|
8
|
+
|
5
9
|
def validate_each(record, attribute, _value)
|
6
|
-
return true
|
10
|
+
return true unless record.send(attribute).attached?
|
7
11
|
|
12
|
+
types = authorized_types(record)
|
13
|
+
return true if types.empty?
|
14
|
+
|
8
15
|
files = Array.wrap(record.send(attribute))
|
9
16
|
|
10
|
-
errors_options = { authorized_types: types_to_human_format }
|
17
|
+
errors_options = { authorized_types: types_to_human_format(types) }
|
11
18
|
errors_options[:message] = options[:message] if options[:message].present?
|
12
19
|
|
13
20
|
files.each do |file|
|
14
|
-
next if is_valid?(file)
|
21
|
+
next if is_valid?(file, types)
|
15
22
|
|
16
23
|
errors_options[:content_type] = content_type(file)
|
17
24
|
record.errors.add(attribute, :content_type_invalid, **errors_options)
|
@@ -19,10 +26,9 @@ module ActiveStorageValidations
|
|
19
26
|
end
|
20
27
|
end
|
21
28
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
@types = (Array.wrap(options[:with]) + Array.wrap(options[:in])).compact.map do |type|
|
29
|
+
def authorized_types(record)
|
30
|
+
flat_options = unfold_procs(record, self.options, AVAILABLE_CHECKS)
|
31
|
+
(Array.wrap(flat_options[:with]) + Array.wrap(flat_options[:in])).compact.map do |type|
|
26
32
|
if type.is_a?(Regexp)
|
27
33
|
type
|
28
34
|
else
|
@@ -31,7 +37,7 @@ module ActiveStorageValidations
|
|
31
37
|
end
|
32
38
|
end
|
33
39
|
|
34
|
-
def types_to_human_format
|
40
|
+
def types_to_human_format(types)
|
35
41
|
types
|
36
42
|
.map { |type| type.to_s.split('/').last.upcase }
|
37
43
|
.join(', ')
|
@@ -41,7 +47,7 @@ module ActiveStorageValidations
|
|
41
47
|
file.blob.present? && file.blob.content_type
|
42
48
|
end
|
43
49
|
|
44
|
-
def is_valid?(file)
|
50
|
+
def is_valid?(file, types)
|
45
51
|
file_type = content_type(file)
|
46
52
|
types.any? do |type|
|
47
53
|
type == file_type || (type.is_a?(Regexp) && type.match?(file_type.to_s))
|
@@ -4,25 +4,30 @@ require_relative 'metadata.rb'
|
|
4
4
|
|
5
5
|
module ActiveStorageValidations
|
6
6
|
class DimensionValidator < ActiveModel::EachValidator # :nodoc
|
7
|
+
include OptionProcUnfolding
|
8
|
+
|
7
9
|
AVAILABLE_CHECKS = %i[width height min max].freeze
|
8
10
|
|
9
|
-
def
|
11
|
+
def process_options(record)
|
12
|
+
flat_options = unfold_procs(record, self.options, AVAILABLE_CHECKS)
|
13
|
+
|
10
14
|
[:width, :height].each do |length|
|
11
|
-
if
|
12
|
-
if range =
|
15
|
+
if flat_options[length] and flat_options[length].is_a?(Hash)
|
16
|
+
if (range = flat_options[length][:in])
|
13
17
|
raise ArgumentError, ":in must be a Range" unless range.is_a?(Range)
|
14
|
-
|
18
|
+
flat_options[length][:min], flat_options[length][:max] = range.min, range.max
|
15
19
|
end
|
16
20
|
end
|
17
21
|
end
|
18
22
|
[:min, :max].each do |dim|
|
19
|
-
if range =
|
23
|
+
if (range = flat_options[dim])
|
20
24
|
raise ArgumentError, ":#{dim} must be a Range (width..height)" unless range.is_a?(Range)
|
21
|
-
|
22
|
-
|
25
|
+
flat_options[:width] = { dim => range.first }
|
26
|
+
flat_options[:height] = { dim => range.last }
|
23
27
|
end
|
24
28
|
end
|
25
|
-
|
29
|
+
|
30
|
+
flat_options
|
26
31
|
end
|
27
32
|
|
28
33
|
|
@@ -64,26 +69,27 @@ module ActiveStorageValidations
|
|
64
69
|
|
65
70
|
|
66
71
|
def is_valid?(record, attribute, file_metadata)
|
72
|
+
flat_options = process_options(record)
|
67
73
|
# Validation fails unless file metadata contains valid width and height.
|
68
74
|
if file_metadata[:width].to_i <= 0 || file_metadata[:height].to_i <= 0
|
69
|
-
add_error(record, attribute,
|
75
|
+
add_error(record, attribute, :image_metadata_missing)
|
70
76
|
return false
|
71
77
|
end
|
72
78
|
|
73
79
|
# Validation based on checks :min and :max (:min, :max has higher priority to :width, :height).
|
74
|
-
if
|
75
|
-
if
|
76
|
-
(
|
77
|
-
(
|
80
|
+
if flat_options[:min] || flat_options[:max]
|
81
|
+
if flat_options[:min] && (
|
82
|
+
(flat_options[:width][:min] && file_metadata[:width] < flat_options[:width][:min]) ||
|
83
|
+
(flat_options[:height][:min] && file_metadata[:height] < flat_options[:height][:min])
|
78
84
|
)
|
79
|
-
add_error(record, attribute,
|
85
|
+
add_error(record, attribute, :dimension_min_inclusion, width: flat_options[:width][:min], height: flat_options[:height][:min])
|
80
86
|
return false
|
81
87
|
end
|
82
|
-
if
|
83
|
-
(
|
84
|
-
(
|
88
|
+
if flat_options[:max] && (
|
89
|
+
(flat_options[:width][:max] && file_metadata[:width] > flat_options[:width][:max]) ||
|
90
|
+
(flat_options[:height][:max] && file_metadata[:height] > flat_options[:height][:max])
|
85
91
|
)
|
86
|
-
add_error(record, attribute,
|
92
|
+
add_error(record, attribute, :dimension_max_inclusion, width: flat_options[:width][:max], height: flat_options[:height][:max])
|
87
93
|
return false
|
88
94
|
end
|
89
95
|
|
@@ -91,24 +97,24 @@ module ActiveStorageValidations
|
|
91
97
|
else
|
92
98
|
width_or_height_invalid = false
|
93
99
|
[:width, :height].each do |length|
|
94
|
-
next unless
|
95
|
-
if
|
96
|
-
if
|
97
|
-
add_error(record, attribute,
|
100
|
+
next unless flat_options[length]
|
101
|
+
if flat_options[length].is_a?(Hash)
|
102
|
+
if flat_options[length][:in] && (file_metadata[length] < flat_options[length][:min] || file_metadata[length] > flat_options[length][:max])
|
103
|
+
add_error(record, attribute, :"dimension_#{length}_inclusion", min: flat_options[length][:min], max: flat_options[length][:max])
|
98
104
|
width_or_height_invalid = true
|
99
105
|
else
|
100
|
-
if
|
101
|
-
add_error(record, attribute,
|
106
|
+
if flat_options[length][:min] && file_metadata[length] < flat_options[length][:min]
|
107
|
+
add_error(record, attribute, :"dimension_#{length}_greater_than_or_equal_to", length: flat_options[length][:min])
|
102
108
|
width_or_height_invalid = true
|
103
109
|
end
|
104
|
-
if
|
105
|
-
add_error(record, attribute,
|
110
|
+
if flat_options[length][:max] && file_metadata[length] > flat_options[length][:max]
|
111
|
+
add_error(record, attribute, :"dimension_#{length}_less_than_or_equal_to", length: flat_options[length][:max])
|
106
112
|
width_or_height_invalid = true
|
107
113
|
end
|
108
114
|
end
|
109
115
|
else
|
110
|
-
if file_metadata[length] !=
|
111
|
-
add_error(record, attribute,
|
116
|
+
if file_metadata[length] != flat_options[length]
|
117
|
+
add_error(record, attribute, :"dimension_#{length}_equal_to", length: flat_options[length])
|
112
118
|
width_or_height_invalid = true
|
113
119
|
end
|
114
120
|
end
|
@@ -120,10 +126,10 @@ module ActiveStorageValidations
|
|
120
126
|
true # valid file
|
121
127
|
end
|
122
128
|
|
123
|
-
def add_error(record, attribute,
|
124
|
-
|
125
|
-
return if record.errors.added?(attribute,
|
126
|
-
record.errors.add(attribute,
|
129
|
+
def add_error(record, attribute, default_message, **attrs)
|
130
|
+
message = options[:message].presence || default_message
|
131
|
+
return if record.errors.added?(attribute, message)
|
132
|
+
record.errors.add(attribute, message, **attrs)
|
127
133
|
end
|
128
134
|
|
129
135
|
end
|
@@ -2,11 +2,12 @@
|
|
2
2
|
|
3
3
|
module ActiveStorageValidations
|
4
4
|
class LimitValidator < ActiveModel::EachValidator # :nodoc:
|
5
|
+
include OptionProcUnfolding
|
6
|
+
|
5
7
|
AVAILABLE_CHECKS = %i[max min].freeze
|
6
8
|
|
7
9
|
def check_validity!
|
8
10
|
return true if AVAILABLE_CHECKS.any? { |argument| options.key?(argument) }
|
9
|
-
|
10
11
|
raise ArgumentError, 'You must pass either :max or :min to the validator'
|
11
12
|
end
|
12
13
|
|
@@ -14,19 +15,20 @@ module ActiveStorageValidations
|
|
14
15
|
return true unless record.send(attribute).attached?
|
15
16
|
|
16
17
|
files = Array.wrap(record.send(attribute)).compact.uniq
|
17
|
-
|
18
|
+
flat_options = unfold_procs(record, self.options, AVAILABLE_CHECKS)
|
19
|
+
errors_options = { min: flat_options[:min], max: flat_options[:max] }
|
18
20
|
|
19
|
-
return true if files_count_valid?(files.count)
|
21
|
+
return true if files_count_valid?(files.count, flat_options)
|
20
22
|
record.errors.add(attribute, options[:message].presence || :limit_out_of_range, **errors_options)
|
21
23
|
end
|
22
24
|
|
23
|
-
def files_count_valid?(count)
|
24
|
-
if
|
25
|
-
count >=
|
26
|
-
elsif
|
27
|
-
count <=
|
28
|
-
elsif
|
29
|
-
count >=
|
25
|
+
def files_count_valid?(count, flat_options)
|
26
|
+
if flat_options[:max].present? && flat_options[:min].present?
|
27
|
+
count >= flat_options[:min] && count <= flat_options[:max]
|
28
|
+
elsif flat_options[:max].present?
|
29
|
+
count <= flat_options[:max]
|
30
|
+
elsif flat_options[:min].present?
|
31
|
+
count >= flat_options[:min]
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ActiveStorageValidations
|
2
|
+
module OptionProcUnfolding
|
3
|
+
|
4
|
+
def unfold_procs(record, object, only_keys = nil)
|
5
|
+
case object
|
6
|
+
when Hash
|
7
|
+
object.merge(object) { |key, value| only_keys&.exclude?(key) ? unfold_procs(record, value, []) : unfold_procs(record, value) }
|
8
|
+
when Array
|
9
|
+
object.map { |o| unfold_procs(record, o, only_keys) }
|
10
|
+
else
|
11
|
+
object.is_a?(Proc) ? object.call(record) : object
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -2,14 +2,15 @@
|
|
2
2
|
|
3
3
|
module ActiveStorageValidations
|
4
4
|
class SizeValidator < ActiveModel::EachValidator # :nodoc:
|
5
|
+
include OptionProcUnfolding
|
6
|
+
|
5
7
|
delegate :number_to_human_size, to: ActiveSupport::NumberHelper
|
6
8
|
|
7
9
|
AVAILABLE_CHECKS = %i[less_than less_than_or_equal_to greater_than greater_than_or_equal_to between].freeze
|
8
10
|
|
9
11
|
def check_validity!
|
10
12
|
return true if AVAILABLE_CHECKS.any? { |argument| options.key?(argument) }
|
11
|
-
|
12
|
-
raise ArgumentError, 'You must pass either :less_than, :greater_than, or :between to the validator'
|
13
|
+
raise ArgumentError, 'You must pass either :less_than(_or_equal_to), :greater_than(_or_equal_to), or :between to the validator'
|
13
14
|
end
|
14
15
|
|
15
16
|
def validate_each(record, attribute, _value)
|
@@ -20,39 +21,40 @@ module ActiveStorageValidations
|
|
20
21
|
|
21
22
|
errors_options = {}
|
22
23
|
errors_options[:message] = options[:message] if options[:message].present?
|
24
|
+
flat_options = unfold_procs(record, self.options, AVAILABLE_CHECKS)
|
23
25
|
|
24
26
|
files.each do |file|
|
25
|
-
next if content_size_valid?(file.blob.byte_size)
|
27
|
+
next if content_size_valid?(file.blob.byte_size, flat_options)
|
26
28
|
|
27
29
|
errors_options[:file_size] = number_to_human_size(file.blob.byte_size)
|
28
|
-
errors_options[:min_size] = number_to_human_size(min_size)
|
29
|
-
errors_options[:max_size] = number_to_human_size(max_size)
|
30
|
+
errors_options[:min_size] = number_to_human_size(min_size(flat_options))
|
31
|
+
errors_options[:max_size] = number_to_human_size(max_size(flat_options))
|
30
32
|
|
31
33
|
record.errors.add(attribute, :file_size_out_of_range, **errors_options)
|
32
34
|
break
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
36
|
-
def content_size_valid?(file_size)
|
37
|
-
if
|
38
|
-
|
39
|
-
elsif
|
40
|
-
file_size <
|
41
|
-
elsif
|
42
|
-
file_size <=
|
43
|
-
elsif
|
44
|
-
file_size >
|
45
|
-
elsif
|
46
|
-
file_size >=
|
38
|
+
def content_size_valid?(file_size, flat_options)
|
39
|
+
if flat_options[:between].present?
|
40
|
+
flat_options[:between].include?(file_size)
|
41
|
+
elsif flat_options[:less_than].present?
|
42
|
+
file_size < flat_options[:less_than]
|
43
|
+
elsif flat_options[:less_than_or_equal_to].present?
|
44
|
+
file_size <= flat_options[:less_than_or_equal_to]
|
45
|
+
elsif flat_options[:greater_than].present?
|
46
|
+
file_size > flat_options[:greater_than]
|
47
|
+
elsif flat_options[:greater_than_or_equal_to].present?
|
48
|
+
file_size >= flat_options[:greater_than_or_equal_to]
|
47
49
|
end
|
48
50
|
end
|
49
51
|
|
50
|
-
def min_size
|
51
|
-
|
52
|
+
def min_size(flat_options)
|
53
|
+
flat_options[:between]&.min || flat_options[:greater_than] || flat_options[:greater_than_or_equal_to]
|
52
54
|
end
|
53
55
|
|
54
|
-
def max_size
|
55
|
-
|
56
|
+
def max_size(flat_options)
|
57
|
+
flat_options[:between]&.max || flat_options[:less_than] || flat_options[:less_than_or_equal_to]
|
56
58
|
end
|
57
59
|
end
|
58
60
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'active_storage_validations/railtie'
|
4
4
|
require 'active_storage_validations/engine'
|
5
|
+
require 'active_storage_validations/option_proc_unfolding'
|
5
6
|
require 'active_storage_validations/attached_validator'
|
6
7
|
require 'active_storage_validations/content_type_validator'
|
7
8
|
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: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Igor Kasyanchuk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-10-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|
@@ -164,6 +164,20 @@ dependencies:
|
|
164
164
|
- - ">="
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: globalid
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
167
181
|
description: Validations for Active Storage (presence)
|
168
182
|
email:
|
169
183
|
- igorkasyanchuk@gmail.com
|
@@ -187,6 +201,7 @@ files:
|
|
187
201
|
- config/locales/tr.yml
|
188
202
|
- config/locales/uk.yml
|
189
203
|
- config/locales/vi.yml
|
204
|
+
- config/locales/zh-CN.yml
|
190
205
|
- lib/active_storage_validations.rb
|
191
206
|
- lib/active_storage_validations/aspect_ratio_validator.rb
|
192
207
|
- lib/active_storage_validations/attached_validator.rb
|
@@ -200,6 +215,7 @@ files:
|
|
200
215
|
- lib/active_storage_validations/matchers/dimension_validator_matcher.rb
|
201
216
|
- lib/active_storage_validations/matchers/size_validator_matcher.rb
|
202
217
|
- lib/active_storage_validations/metadata.rb
|
218
|
+
- lib/active_storage_validations/option_proc_unfolding.rb
|
203
219
|
- lib/active_storage_validations/railtie.rb
|
204
220
|
- lib/active_storage_validations/size_validator.rb
|
205
221
|
- lib/active_storage_validations/version.rb
|
@@ -223,7 +239,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
223
239
|
- !ruby/object:Gem::Version
|
224
240
|
version: '0'
|
225
241
|
requirements: []
|
226
|
-
rubygems_version: 3.
|
242
|
+
rubygems_version: 3.3.7
|
227
243
|
signing_key:
|
228
244
|
specification_version: 4
|
229
245
|
summary: Validations for Active Storage
|