active_storage_validations 0.9.8 → 1.0.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 +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
|
[![MiniTest](https://github.com/igorkasyanchuk/active_storage_validations/workflows/MiniTest/badge.svg)](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
|