active_storage_validations 1.1.4 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +56 -18
  3. data/config/locales/da.yml +33 -0
  4. data/config/locales/de.yml +5 -0
  5. data/config/locales/en.yml +5 -0
  6. data/config/locales/es.yml +5 -0
  7. data/config/locales/fr.yml +5 -0
  8. data/config/locales/it.yml +5 -0
  9. data/config/locales/ja.yml +5 -0
  10. data/config/locales/nl.yml +5 -0
  11. data/config/locales/pl.yml +5 -0
  12. data/config/locales/pt-BR.yml +5 -0
  13. data/config/locales/ru.yml +5 -0
  14. data/config/locales/sv.yml +10 -1
  15. data/config/locales/tr.yml +5 -0
  16. data/config/locales/uk.yml +5 -0
  17. data/config/locales/vi.yml +5 -0
  18. data/config/locales/zh-CN.yml +5 -0
  19. data/lib/active_storage_validations/attached_validator.rb +3 -3
  20. data/lib/active_storage_validations/base_size_validator.rb +66 -0
  21. data/lib/active_storage_validations/concerns/errorable.rb +2 -2
  22. data/lib/active_storage_validations/matchers/aspect_ratio_validator_matcher.rb +6 -15
  23. data/lib/active_storage_validations/matchers/attached_validator_matcher.rb +5 -13
  24. data/lib/active_storage_validations/matchers/base_size_validator_matcher.rb +134 -0
  25. data/lib/active_storage_validations/matchers/concerns/attachable.rb +48 -0
  26. data/lib/active_storage_validations/matchers/concerns/contextable.rb +20 -8
  27. data/lib/active_storage_validations/matchers/concerns/validatable.rb +9 -3
  28. data/lib/active_storage_validations/matchers/content_type_validator_matcher.rb +5 -2
  29. data/lib/active_storage_validations/matchers/dimension_validator_matcher.rb +6 -15
  30. data/lib/active_storage_validations/matchers/processable_image_validator_matcher.rb +78 -0
  31. data/lib/active_storage_validations/matchers/size_validator_matcher.rb +4 -139
  32. data/lib/active_storage_validations/matchers/total_size_validator_matcher.rb +40 -0
  33. data/lib/active_storage_validations/matchers.rb +2 -0
  34. data/lib/active_storage_validations/metadata.rb +20 -2
  35. data/lib/active_storage_validations/size_validator.rb +4 -49
  36. data/lib/active_storage_validations/total_size_validator.rb +49 -0
  37. data/lib/active_storage_validations/version.rb +1 -1
  38. data/lib/active_storage_validations.rb +2 -1
  39. metadata +31 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 305a698168303d4889b8ba6b3972201842af8679758f6f9c81140658a0abdc8a
4
- data.tar.gz: 414b60017f2da20463daa783e56028c927c2090a80e7728877f569323ec0b60a
3
+ metadata.gz: c4e1690b53c320459f3dcd874f52680d67b8e1f1b6dc68eccff486c5a664695a
4
+ data.tar.gz: 5d1a163646400c3ee50feff6c2c847408fa8c54f42457d9493ddfa0c4f900ab0
5
5
  SHA512:
6
- metadata.gz: 48123a7a880a4f8e1b7680d3ea21b2e54c6f13b884b351e11c3f912fcdeec01efe24a0d6fc26b1021ec9b92460f6c6df321c869d9a8ce4e1848d339b1e35b0ca
7
- data.tar.gz: faee600c94d2534a943feb4eebe14574341e3920e9bfd03fe663afad85c80e01c8cb7f95ced957ce333a323553798c6d73c0f8bffb33bdc185b922047f176b20
6
+ metadata.gz: 520513aab9962df2b30156c44685d3db9e86bb5bf73702dd11c54fd1834548bd5931d7d0841b26d9bc4bea3f4f765d72593565ca5c0c2c84efe414760f3e16b3
7
+ data.tar.gz: 4fecb3d1b7b33a2c78a12747fe1b6a0509e419dd1a54e1e5c089044f627d68c7eead6aaa486d2baa7bb7ebff2f4654a60262718abf9524c69ea8281713cc626b
data/README.md CHANGED
@@ -17,6 +17,7 @@ This gems doing it for you. Just use `attached: true` or `content_type: 'image/p
17
17
  * validates if file(s) attached
18
18
  * validates content type
19
19
  * validates size of files
20
+ * validates total size of files
20
21
  * validates dimension of images/videos
21
22
  * validates number of uploaded files (min/max required)
22
23
  * validates aspect ratio (if square, portrait, landscape, is_16_9, ...)
@@ -62,13 +63,13 @@ class Project < ApplicationRecord
62
63
  validates :logo, attached: true, size: { less_than: 100.megabytes , message: 'is too large' }
63
64
  validates :preview, attached: true, size: { between: 1.kilobyte..100.megabytes , message: 'is not given between size' }
64
65
  validates :attachment, attached: true, content_type: { in: 'application/pdf', message: 'is not a PDF' }
65
- validates :documents, limit: { min: 1, max: 3 }
66
+ validates :documents, limit: { min: 1, max: 3 }, total_size: { less_than: 5.megabytes }
66
67
  end
67
68
  ```
68
69
 
69
70
  ### More examples
70
71
 
71
- - Content type validation using symbols or regex. The symbol types must be registered by [`Marcel::EXTENSIONS`](https://github.com/rails/marcel/blob/main/lib/marcel/tables.rb) that's used by this gem to infer the full content type.
72
+ - Content type validation using symbols or regex.
72
73
 
73
74
  ```ruby
74
75
  class User < ApplicationRecord
@@ -82,6 +83,12 @@ class User < ApplicationRecord
82
83
  validates :avatar, content_type: /\Aimage\/.*\z/
83
84
  end
84
85
  ```
86
+ Please note that the symbol types must be registered by [`Marcel::EXTENSIONS`](https://github.com/rails/marcel/blob/main/lib/marcel/tables.rb) that's used by this gem to infer the full content type.
87
+ Example code for adding a new content type to Marcel:
88
+ ```ruby
89
+ # config/initializers/mime_types.rb
90
+ Marcel::MimeType.extend "application/ino", extensions: %w(ino), parents: "text/plain" # Registering arduino INO files
91
+ ```
85
92
 
86
93
  - Dimension validation with `width`, `height` and `in`.
87
94
 
@@ -153,18 +160,23 @@ en:
153
160
  file_size_not_greater_than: "file size must be greater than %{min_size} (current size is %{file_size})"
154
161
  file_size_not_greater_than_or_equal_to: "file size must be greater than or equal to %{min_size} (current size is %{file_size})"
155
162
  file_size_not_between: "file size must be between %{min_size} and %{max_size} (current size is %{file_size})"
163
+ total_file_size_not_less_than: "total file size must be less than %{max_size} (current size is %{total_file_size})"
164
+ total_file_size_not_less_than_or_equal_to: "total file size must be less than or equal to %{max_size} (current size is %{total_file_size})"
165
+ total_file_size_not_greater_than: "total file size must be greater than %{min_size} (current size is %{total_file_size})"
166
+ total_file_size_not_greater_than_or_equal_to: "total file size must be greater than or equal to %{min_size} (current size is %{total_file_size})"
167
+ total_file_size_not_between: "total file size must be between %{min_size} and %{max_size} (current size is %{total_file_size})"
156
168
  limit_out_of_range: "total number is out of range"
157
169
  image_metadata_missing: "is not a valid image"
158
- dimension_min_inclusion: "must be greater than or equal to %{width} x %{height} pixel."
159
- dimension_max_inclusion: "must be less than or equal to %{width} x %{height} pixel."
160
- dimension_width_inclusion: "width is not included between %{min} and %{max} pixel."
161
- dimension_height_inclusion: "height is not included between %{min} and %{max} pixel."
162
- dimension_width_greater_than_or_equal_to: "width must be greater than or equal to %{length} pixel."
163
- dimension_height_greater_than_or_equal_to: "height must be greater than or equal to %{length} pixel."
164
- dimension_width_less_than_or_equal_to: "width must be less than or equal to %{length} pixel."
165
- dimension_height_less_than_or_equal_to: "height must be less than or equal to %{length} pixel."
166
- dimension_width_equal_to: "width must be equal to %{length} pixel."
167
- dimension_height_equal_to: "height must be equal to %{length} pixel."
170
+ dimension_min_inclusion: "must be greater than or equal to %{width} x %{height} pixel"
171
+ dimension_max_inclusion: "must be less than or equal to %{width} x %{height} pixel"
172
+ dimension_width_inclusion: "width is not included between %{min} and %{max} pixel"
173
+ dimension_height_inclusion: "height is not included between %{min} and %{max} pixel"
174
+ dimension_width_greater_than_or_equal_to: "width must be greater than or equal to %{length} pixel"
175
+ dimension_height_greater_than_or_equal_to: "height must be greater than or equal to %{length} pixel"
176
+ dimension_width_less_than_or_equal_to: "width must be less than or equal to %{length} pixel"
177
+ dimension_height_less_than_or_equal_to: "height must be less than or equal to %{length} pixel"
178
+ dimension_width_equal_to: "width must be equal to %{length} pixel"
179
+ dimension_height_equal_to: "height must be equal to %{length} pixel"
168
180
  aspect_ratio_not_square: "must be a square image"
169
181
  aspect_ratio_not_portrait: "must be a portrait image"
170
182
  aspect_ratio_not_landscape: "must be a landscape image"
@@ -177,7 +189,7 @@ In several cases, Active Storage Validations provides variables to help you cust
177
189
 
178
190
  ### Aspect ratio
179
191
  The keys starting with `aspect_ratio_` support two variables that you can use:
180
- - `aspect_ratio` containing the expected aspect ratio, especially usefull for custom aspect ratio
192
+ - `aspect_ratio` containing the expected aspect ratio, especially useful for custom aspect ratio
181
193
  - `filename` containing the current file name
182
194
 
183
195
  For example :
@@ -204,7 +216,7 @@ The keys starting with `dimension_` support six variables that you can use:
204
216
  - `max` containing the maximum width or height allowed
205
217
  - `width` containing the minimum or maximum width allowed
206
218
  - `height` containing the minimum or maximum width allowed
207
- - `lenght` containing the exact width or height allowed
219
+ - `length` containing the exact width or height allowed
208
220
  - `filename` containing the current file name
209
221
 
210
222
  For example :
@@ -217,7 +229,7 @@ dimension_min_inclusion: "must be greater than or equal to %{width} x %{height}
217
229
  The keys starting with `file_size_not_` support four variables that you can use:
218
230
  - `file_size` containing the current file size
219
231
  - `min` containing the minimum file size
220
- - `max` containing the maxmimum file size
232
+ - `max` containing the maximum file size
221
233
  - `filename` containing the current file name
222
234
 
223
235
  For example :
@@ -226,6 +238,18 @@ For example :
226
238
  file_size_not_between: "file size must be between %{min_size} and %{max_size} (current size is %{file_size})"
227
239
  ```
228
240
 
241
+ ### Total file size
242
+ The keys starting with `total_file_size_not_` support three variables that you can use:
243
+ - `total_file_size` containing the current total file size
244
+ - `min` containing the minimum file size
245
+ - `max` containing the maximum file size
246
+
247
+ For example :
248
+
249
+ ```yml
250
+ total_file_size_not_between: "total file size must be between %{min_size} and %{max_size} (current size is %{total_file_size})"
251
+ ```
252
+
229
253
  ### Number of files
230
254
  The `limit_out_of_range` key supports two variables that you can use:
231
255
  - `min` containing the minimum number of files
@@ -252,7 +276,6 @@ image_not_processable: "is not a valid image (file: %{filename})"
252
276
  Add this line to your application's Gemfile:
253
277
 
254
278
  ```ruby
255
- # Rails 5.2 and Rails 6
256
279
  gem 'active_storage_validations'
257
280
 
258
281
  # Optional, to use :dimension validator or :aspect_ratio validator
@@ -274,7 +297,8 @@ Very simple example of validation with file attached, content type check and cus
274
297
  [![Sample](https://raw.githubusercontent.com/igorkasyanchuk/active_storage_validations/master/docs/preview.png)](https://raw.githubusercontent.com/igorkasyanchuk/active_storage_validations/master/docs/preview.png)
275
298
 
276
299
  ## Test matchers
277
- Provides RSpec-compatible and Minitest-compatible matchers for testing the validators. Only `aspect_ratio`, `attached`, `content_type`, `dimension` and `size` validators currently have their matcher developped.
300
+
301
+ Provides RSpec-compatible and Minitest-compatible matchers for testing the validators. Only `aspect_ratio`, `attached`, `content_type`, `processable_image`, `dimension`, `size` and `total_size` validators currently have their matcher developed.
278
302
 
279
303
  ### RSpec
280
304
 
@@ -304,6 +328,9 @@ describe User do
304
328
  # attached
305
329
  it { is_expected.to validate_attached_of(:avatar) }
306
330
 
331
+ # processable_image
332
+ it { is_expected.to validate_processable_image_of(:avatar) }
333
+
307
334
  # content_type:
308
335
  # #allowing, #rejecting
309
336
  it { is_expected.to validate_content_type_of(:avatar).allowing('image/png', 'image/gif') }
@@ -327,6 +354,14 @@ describe User do
327
354
  it { is_expected.to validate_size_of(:avatar).greater_than(1.kilobyte) }
328
355
  it { is_expected.to validate_size_of(:avatar).greater_than_or_equal_to(1.kilobyte) }
329
356
  it { is_expected.to validate_size_of(:avatar).between(100..500.kilobytes) }
357
+
358
+ # total_size:
359
+ # #less_than, #less_than_or_equal_to, #greater_than, #greater_than_or_equal_to, #between
360
+ it { is_expected.to validate_total_size_of(:avatar).less_than(50.kilobytes) }
361
+ it { is_expected.to validate_total_size_of(:avatar).less_than_or_equal_to(50.kilobytes) }
362
+ it { is_expected.to validate_total_size_of(:avatar).greater_than(1.kilobyte) }
363
+ it { is_expected.to validate_total_size_of(:avatar).greater_than_or_equal_to(1.kilobyte) }
364
+ it { is_expected.to validate_total_size_of(:avatar).between(100..500.kilobytes) }
330
365
  end
331
366
  ```
332
367
  (Note that matcher methods are chainable)
@@ -457,7 +492,6 @@ You are welcome to contribute.
457
492
  - https://github.com/vietqhoang
458
493
  - https://github.com/kemenaran
459
494
  - https://github.com/jrmhaig
460
- - https://github.com/tagliala
461
495
  - https://github.com/evedovelli
462
496
  - https://github.com/JuanVqz
463
497
  - https://github.com/luiseugenio
@@ -480,6 +514,10 @@ You are welcome to contribute.
480
514
  - https://github.com/tagliala
481
515
  - https://github.com/ocarreterom
482
516
  - https://github.com/aditya-cherukuri
517
+ - https://github.com/searls
518
+ - https://github.com/yenshirak
519
+ - https://github.com/wataori
520
+ - https://github.com/Scorpahr
483
521
 
484
522
 
485
523
  ## License
@@ -0,0 +1,33 @@
1
+ # Danish
2
+ da:
3
+ errors:
4
+ messages:
5
+ content_type_invalid: "har en ugyldig indholdstype"
6
+ file_size_not_less_than: "filstørrelsen skal være mindre end %{max_size} (den nuværende størrelse er %{file_size})"
7
+ file_size_not_less_than_or_equal_to: "filstørrelsen skal være mindre end eller lig med %{max_size} (den nuværende størrelse er %{file_size})"
8
+ file_size_not_greater_than: "filstørrelsen skal være større end %{min_size} (den nuværende størrelse er %{file_size})"
9
+ file_size_not_greater_than_or_equal_to: "filstørrelsen skal være større end eller lig med %{min_size} (den nuværende størrelse er %{file_size})"
10
+ file_size_not_between: "filstørrelsen skal være mellem %{min_size} og %{max_size} (den nuværende størrelse er %{file_size})"
11
+ total_file_size_not_less_than: "den samlede filstørrelse skal være mindre end %{max_size} (aktuel størrelse er %{total_file_size})"
12
+ total_file_size_not_less_than_or_equal_to: "den samlede filstørrelse skal være mindre end eller lig med %{max_size} (aktuel størrelse er %{total_file_size})"
13
+ total_file_size_not_greater_than: "den samlede filstørrelse skal være større end %{min_size} (aktuel størrelse er %{total_file_size})"
14
+ total_file_size_not_greater_than_or_equal_to: "den samlede filstørrelse skal være større end eller lig med %{min_size} (aktuel størrelse er %{total_file_size})"
15
+ total_file_size_not_between: "den samlede filstørrelse skal være mellem %{min_size} og %{max_size} (aktuel størrelse er %{total_file_size})"
16
+ limit_out_of_range: "det samlede antal er uden for rækkevidde"
17
+ image_metadata_missing: "er ikke et gyldigt billede"
18
+ dimension_min_inclusion: "skal være større end eller lig med %{width} x %{height} pixel"
19
+ dimension_max_inclusion: "skal være mindre end eller lig med %{width} x %{height} pixel"
20
+ dimension_width_inclusion: "bredden er ikke inkluderet mellem %{min} og %{max} pixel"
21
+ dimension_height_inclusion: "højden er ikke inkluderet mellem %{min} og %{max} pixel"
22
+ dimension_width_greater_than_or_equal_to: "bredden skal være større end eller lig med %{length} pixel"
23
+ dimension_height_greater_than_or_equal_to: "højden skal være større end eller lig med %{length} pixel"
24
+ dimension_width_less_than_or_equal_to: "bredden skal være mindre end eller lig med %{length} pixel"
25
+ dimension_height_less_than_or_equal_to: "højden skal være mindre end eller lig med %{length} pixel"
26
+ dimension_width_equal_to: "bredden skal være lig med %{length} pixel"
27
+ dimension_height_equal_to: "højden skal være lig med %{length} pixel"
28
+ aspect_ratio_not_square: "skal være et kvadratisk billede"
29
+ aspect_ratio_not_portrait: "skal være et portrætbillede"
30
+ aspect_ratio_not_landscape: "skal være et landskabsbillede"
31
+ aspect_ratio_is_not: "skal have et størrelsesforhold på %{aspect_ratio}"
32
+ aspect_ratio_unknown: "har et ukendt størrelsesforhold"
33
+ image_not_processable: "er ikke et gyldigt billede"
@@ -7,6 +7,11 @@ de:
7
7
  file_size_not_greater_than: "Dateigröße muss größer als %{min_size} sein (aktuelle Dateigröße ist %{file_size})"
8
8
  file_size_not_greater_than_or_equal_to: "Dateigröße muss größer oder gleich %{min_size} sein (aktuelle Dateigröße ist %{file_size})"
9
9
  file_size_not_between: "Dateigröße muss zwischen %{min_size} und %{max_size} liegen (aktuelle Dateigröße ist %{file_size})"
10
+ total_file_size_not_less_than: "Die gesamte Dateigröße muss kleiner als %{max_size} sein (aktuelle Dateigröße ist %{total_file_size})"
11
+ total_file_size_not_less_than_or_equal_to: "Die gesamte Dateigröße muss kleiner oder gleich %{max_size} sein (aktuelle Dateigröße ist %{total_file_size})"
12
+ total_file_size_not_greater_than: "Die gesamte Dateigröße muss größer als %{min_size} sein (aktuelle Dateigröße ist %{total_file_size})"
13
+ total_file_size_not_greater_than_or_equal_to: "Die gesamte Dateigröße muss größer oder gleich %{min_size} sein (aktuelle Dateigröße ist %{total_file_size})"
14
+ total_file_size_not_between: "Die gesamte Dateigröße muss zwischen %{min_size} und %{max_size} liegen (aktuelle Dateigröße ist %{total_file_size})"
10
15
  limit_out_of_range: "Anzahl ist außerhalb des gültigen Bereichs"
11
16
  image_metadata_missing: "ist kein gültiges Bild"
12
17
  dimension_min_inclusion: "muss größer oder gleich %{width} x %{height} Pixel sein"
@@ -7,6 +7,11 @@ en:
7
7
  file_size_not_greater_than: "file size must be greater than %{min_size} (current size is %{file_size})"
8
8
  file_size_not_greater_than_or_equal_to: "file size must be greater than or equal to %{min_size} (current size is %{file_size})"
9
9
  file_size_not_between: "file size must be between %{min_size} and %{max_size} (current size is %{file_size})"
10
+ total_file_size_not_less_than: "total file size must be less than %{max_size} (current size is %{total_file_size})"
11
+ total_file_size_not_less_than_or_equal_to: "total file size must be less than or equal to %{max_size} (current size is %{total_file_size})"
12
+ total_file_size_not_greater_than: "total file size must be greater than %{min_size} (current size is %{total_file_size})"
13
+ total_file_size_not_greater_than_or_equal_to: "total file size must be greater than or equal to %{min_size} (current size is %{total_file_size})"
14
+ total_file_size_not_between: "total file size must be between %{min_size} and %{max_size} (current size is %{total_file_size})"
10
15
  limit_out_of_range: "total number is out of range"
11
16
  image_metadata_missing: "is not a valid image"
12
17
  dimension_min_inclusion: "must be greater than or equal to %{width} x %{height} pixel"
@@ -7,6 +7,11 @@ es:
7
7
  file_size_not_greater_than: "el tamaño del archivo debe ser mayor que %{min_size} (el tamaño actual es %{file_size})"
8
8
  file_size_not_greater_than_or_equal_to: "el tamaño del archivo debe ser mayor o igual a %{min_size} (el tamaño actual es %{file_size})"
9
9
  file_size_not_between: "el tamaño del archivo debe estar entre %{min_size} y %{max_size} (el tamaño actual es %{file_size})"
10
+ total_file_size_not_less_than: "el tamaño total del archivo debe ser inferior a %{max_size} (el tamaño actual es %{total_file_size})"
11
+ total_file_size_not_less_than_or_equal_to: "el tamaño total del archivo debe ser menor o igual a %{max_size} (el tamaño actual es %{total_file_size})"
12
+ total_file_size_not_greater_than: "el tamaño total del archivo debe ser mayor que %{min_size} (el tamaño actual es %{total_file_size})"
13
+ total_file_size_not_greater_than_or_equal_to: "el tamaño total del archivo debe ser mayor o igual a %{min_size} (el tamaño actual es %{total_file_size})"
14
+ total_file_size_not_between: "el tamaño total del archivo debe estar entre %{min_size} y %{max_size} (el tamaño actual es %{total_file_size})"
10
15
  limit_out_of_range: "el número total está fuera de rango"
11
16
  image_metadata_missing: "no es una imagen válida"
12
17
  dimension_min_inclusion: "debe ser mayor o igual a %{width} x %{height} pixel"
@@ -7,6 +7,11 @@ fr:
7
7
  file_size_not_greater_than: "la taille du fichier doit être supérieure à %{min_size} (la taille actuelle est %{file_size})"
8
8
  file_size_not_greater_than_or_equal_to: "la taille du fichier doit être supérieure ou égale à %{min_size} (la taille actuelle est %{file_size})"
9
9
  file_size_not_between: "la taille du fichier doit être comprise entre %{min_size} et %{max_size} (la taille actuelle est %{file_size})"
10
+ total_file_size_not_less_than: "la taille totale des fichiers doit être inférieure à %{max_size} (la taille actuelle est %{total_file_size})"
11
+ total_file_size_not_less_than_or_equal_to: "la taille totale des fichiers doit être inférieure ou égale à %{max_size} (la taille actuelle est %{total_file_size})"
12
+ total_file_size_not_greater_than: "la taille totale des fichiers doit être supérieure à %{min_size} (la taille actuelle est %{total_file_size})"
13
+ total_file_size_not_greater_than_or_equal_to: "la taille totale des fichiers doit être supérieure ou égale à %{min_size} (la taille actuelle est %{total_file_size})"
14
+ total_file_size_not_between: "la taille totale des fichiers doit être comprise entre %{min_size} et %{max_size} (la taille actuelle est %{total_file_size})"
10
15
  limit_out_of_range: "le nombre total est hors limites"
11
16
  image_metadata_missing: "n'est pas une image valide"
12
17
  dimension_min_inclusion: "doit être supérieur ou égal à %{width} x %{height} pixels"
@@ -7,6 +7,11 @@ it:
7
7
  file_size_not_greater_than: "la dimensione del file deve essere maggiore di %{min_size} (la dimensione attuale è %{file_size})"
8
8
  file_size_not_greater_than_or_equal_to: "la dimensione del file deve essere maggiore o uguale a %{min_size} (la dimensione attuale è %{file_size})"
9
9
  file_size_not_between: "la dimensione del file deve essere compresa tra %{min_size} e %{max_size} (la dimensione attuale è %{file_size})"
10
+ total_file_size_not_less_than: "la dimensione totale dei file deve essere inferiore a %{max_size} (la dimensione attuale è %{total_file_size})"
11
+ total_file_size_not_less_than_or_equal_to: "la dimensione totale dei file deve essere minore o uguale a %{max_size} (la dimensione attuale è %{total_file_size})"
12
+ total_file_size_not_greater_than: "la dimensione totale dei file deve essere maggiore di %{min_size} (la dimensione attuale è %{total_file_size})"
13
+ total_file_size_not_greater_than_or_equal_to: "la dimensione totale dei file deve essere maggiore o uguale a %{min_size} (la dimensione attuale è %{total_file_size})"
14
+ total_file_size_not_between: "la dimensione totale dei file deve essere compresa tra %{min_size} e %{max_size} (la dimensione attuale è %{total_file_size})"
10
15
  limit_out_of_range: "il valore è al di fuori dell’intervallo consentito"
11
16
  image_metadata_missing: "non è un'immagine valida"
12
17
  dimension_min_inclusion: "deve essere maggiore o uguale a %{width} x %{height} pixel"
@@ -7,6 +7,11 @@ ja:
7
7
  file_size_not_greater_than: "ファイル サイズは %{min_size} より大きい必要があります (現在のサイズは %{file_size} です)"
8
8
  file_size_not_greater_than_or_equal_to: "ファイル サイズは %{min_size} 以上である必要があります (現在のサイズは %{file_size})"
9
9
  file_size_not_between: "ファイル サイズは %{min_size} から %{max_size} の間でなければなりません (現在のサイズは %{file_size} です)"
10
+ total_file_size_not_less_than: "ファイルの合計サイズは %{max_size} 未満である必要があります (現在のサイズは %{total_file_size})"
11
+ total_file_size_not_less_than_or_equal_to: "ファイルの合計サイズは %{max_size} 以下である必要があります (現在のサイズは %{total_file_size})"
12
+ total_file_size_not_greater_than: "ファイルの合計サイズは %{min_size} より大きくなければなりません (現在のサイズは %{total_file_size} です)"
13
+ total_file_size_not_greater_than_or_equal_to: "ファイルの合計サイズは %{min_size} 以上である必要があります (現在のサイズは %{total_file_size})"
14
+ total_file_size_not_between: "ファイルの合計サイズは %{min_size} から %{max_size} までである必要があります (現在のサイズは %{total_file_size})"
10
15
  limit_out_of_range: "の数が許容範囲外です"
11
16
  image_metadata_missing: "は不正な画像です"
12
17
  dimension_min_inclusion: "は %{width} x %{height} ピクセル以上の大きさにしてください"
@@ -7,6 +7,11 @@ nl:
7
7
  file_size_not_greater_than: "bestandsgrootte moet groter zijn dan %{min_size} (huidige grootte is %{file_size})"
8
8
  file_size_not_greater_than_or_equal_to: "bestandsgrootte moet groter zijn dan of gelijk zijn aan %{min_size} (huidige grootte is %{file_size})"
9
9
  file_size_not_between: "bestandsgrootte moet tussen %{min_size} en %{max_size} liggen (huidige grootte is %{file_size})"
10
+ total_file_size_not_less_than: "totale bestandsgrootte moet kleiner zijn dan %{max_size} (huidige grootte is %{total_file_size})"
11
+ total_file_size_not_less_than_or_equal_to: "totale bestandsgrootte moet kleiner zijn dan of gelijk zijn aan %{max_size} (huidige grootte is %{total_file_size})"
12
+ total_file_size_not_greater_than: "totale bestandsgrootte moet groter zijn dan %{min_size} (huidige grootte is %{total_file_size})"
13
+ total_file_size_not_greater_than_or_equal_to: "totale bestandsgrootte moet groter zijn dan of gelijk zijn aan %{min_size} (huidige grootte is %{total_file_size})"
14
+ total_file_size_not_between: "totale bestandsgrootte moet tussen %{min_size} en %{max_size} liggen (huidige grootte is %{total_file_size})"
10
15
  limit_out_of_range: "totaal aantal valt buiten het vereiste bereik"
11
16
  image_metadata_missing: "is geen geldige afbeelding"
12
17
  dimension_min_inclusion: "moet groter of gelijk zijn aan %{width} x %{height} pixels"
@@ -7,6 +7,11 @@ pl:
7
7
  file_size_not_greater_than: "rozmiar pliku musi być większy niż %{min_size} (obecny rozmiar to %{file_size})"
8
8
  file_size_not_greater_than_or_equal_to: "rozmiar pliku musi być większy lub równy %{min_size} (obecny rozmiar to %{file_size})"
9
9
  file_size_not_between: "rozmiar pliku musi mieścić się w przedziale od %{min_size} do %{max_size} (obecny rozmiar to %{file_size})"
10
+ total_file_size_not_less_than: "całkowity rozmiar pliku musi być mniejszy niż %{max_size} (obecny rozmiar to %{total_file_size})"
11
+ total_file_size_not_less_than_or_equal_to: "całkowity rozmiar pliku musi być mniejszy lub równy %{max_size} (obecny rozmiar to %{total_file_size})"
12
+ total_file_size_not_greater_than: "całkowity rozmiar pliku musi być większy niż %{min_size} (obecny rozmiar to %{total_file_size})"
13
+ total_file_size_not_greater_than_or_equal_to: "całkowity rozmiar pliku musi być większy lub równy %{min_size} (obecny rozmiar to %{total_file_size})"
14
+ total_file_size_not_between: "całkowity rozmiar pliku musi mieścić się w przedziale od %{min_size} do %{max_size} (obecny rozmiar to %{total_file_size})"
10
15
  limit_out_of_range: "ilość przekracza dopuszczalny zakres"
11
16
  image_metadata_missing: "nie jest prawidłowym obrazem"
12
17
  dimension_min_inclusion: "musi być równe lub większe od %{width} x %{height} pixeli"
@@ -7,6 +7,11 @@ pt-BR:
7
7
  file_size_not_greater_than: "o tamanho do arquivo deve ser maior que %{min_size} (o tamanho atual é %{file_size})"
8
8
  file_size_not_greater_than_or_equal_to: "o tamanho do arquivo deve ser maior ou igual a %{min_size} (o tamanho atual é %{file_size})"
9
9
  file_size_not_between: "o tamanho do arquivo deve estar entre %{min_size} e %{max_size} (o tamanho atual é %{file_size})"
10
+ total_file_size_not_less_than: "o tamanho total do arquivo deve ser menor que %{max_size} (o tamanho atual é %{total_file_size})"
11
+ total_file_size_not_less_than_or_equal_to: "o tamanho total do arquivo deve ser menor ou igual a %{max_size} (o tamanho atual é %{total_file_size})"
12
+ total_file_size_not_greater_than: "o tamanho total do arquivo deve ser maior que %{min_size} (o tamanho atual é %{total_file_size})"
13
+ total_file_size_not_greater_than_or_equal_to: "o tamanho total do arquivo deve ser maior ou igual a %{min_size} (o tamanho atual é %{total_file_size})"
14
+ total_file_size_not_between: "o tamanho total do arquivo deve estar entre %{min_size} e %{max_size} (o tamanho atual é %{total_file_size})"
10
15
  limit_out_of_range: "o número total está fora do limite"
11
16
  image_metadata_missing: "não é uma imagem válida"
12
17
  dimension_min_inclusion: "deve ser maior ou igual a %{width} x %{height} pixels"
@@ -7,6 +7,11 @@ ru:
7
7
  file_size_not_greater_than: "размер файла должен быть больше %{min_size} (текущий размер %{file_size})"
8
8
  file_size_not_greater_than_or_equal_to: "размер файла должен быть больше или равен %{min_size} (текущий размер %{file_size})"
9
9
  file_size_not_between: "размер файла должен быть между %{min_size} и %{max_size} (текущий размер %{file_size})"
10
+ total_file_size_not_less_than: "общий размер файла должен быть меньше %{max_size} (текущий размер %{total_file_size})"
11
+ total_file_size_not_less_than_or_equal_to: "общий размер файла должен быть меньше или равен %{max_size} (текущий размер %{total_file_size})"
12
+ total_file_size_not_greater_than: "общий размер файла должен быть больше %{min_size} (текущий размер %{total_file_size})"
13
+ total_file_size_not_greater_than_or_equal_to: "общий размер файла должен быть больше или равен %{min_size} (текущий размер %{total_file_size})"
14
+ total_file_size_not_between: "общий размер файла должен быть между %{min_size} и %{max_size} (текущий размер %{total_file_size})"
10
15
  limit_out_of_range: "количество файлов больше требуемого"
11
16
  image_metadata_missing: "не является допустимым изображением"
12
17
  dimension_min_inclusion: "должен быть больше или равно %{width} x %{height} пикселям"
@@ -2,7 +2,16 @@ sv:
2
2
  errors:
3
3
  messages:
4
4
  content_type_invalid: "Har en ogiltig filtyp"
5
- file_size_out_of_range: "storleken %{file_size} är utanför det krävda intervallet"
5
+ file_size_not_less_than: "filstorleken måste vara mindre än %{max_size} (nuvarande storlek är %{file_size})"
6
+ file_size_not_less_than_or_equal_to: "filstorleken måste vara mindre än eller lika med %{max_size} (nuvarande storlek är %{file_size})"
7
+ file_size_not_greater_than: "filstorleken måste vara större än %{min_size} (nuvarande storlek är %{file_size})"
8
+ file_size_not_greater_than_or_equal_to: "filstorleken måste vara större än eller lika med %{min_size} (nuvarande storlek är %{file_size})"
9
+ file_size_not_between: "filstorleken måste vara mellan %{min_size} och %{max_size} (nuvarande storlek är %{file_size})"
10
+ total_file_size_not_less_than: "total filstorlek måste vara mindre än %{max_size} (nuvarande storlek är %{total_file_size})"
11
+ total_file_size_not_less_than_or_equal_to: "total filstorlek måste vara mindre än eller lika med %{max_size} (nuvarande storlek är %{total_file_size})"
12
+ total_file_size_not_greater_than: "total filstorlek måste vara större än %{min_size} (nuvarande storlek är %{total_file_size})"
13
+ total_file_size_not_greater_than_or_equal_to: "total filstorlek måste vara större än eller lika med %{min_size} (nuvarande storlek är %{total_file_size})"
14
+ total_file_size_not_between: "total filstorlek måste vara mellan %{min_size} och %{max_size} (nuvarande storlek är %{total_file_size})"
6
15
  limit_out_of_range: "antalet filer är utanför det godkända intervallet"
7
16
  image_metadata_missing: "bilden sankar metadata"
8
17
  dimension_min_inclusion: "måste minst vara %{width} x %{height} pixlar"
@@ -7,6 +7,11 @@ tr:
7
7
  file_size_not_greater_than: "dosya boyutu %{min_size} boyutundan büyük olmalıdır (geçerli boyut %{file_size}'dir)"
8
8
  file_size_not_greater_than_or_equal_to: "dosya boyutu %{min_size} değerinden büyük veya eşit olmalıdır (geçerli boyut %{file_size}'dir)"
9
9
  file_size_not_between: "dosya boyutu %{min_size} ile %{max_size} arasında olmalıdır (geçerli boyut %{file_size}'dir)"
10
+ total_file_size_not_less_than: "toplam dosya boyutu %{max_size} boyutundan küçük olmalıdır (geçerli boyut %{total_file_size}'dir)"
11
+ total_file_size_not_less_than_or_equal_to: "toplam dosya boyutu %{max_size} değerinden küçük veya ona eşit olmalıdır (geçerli boyut %{total_file_size}'dir)"
12
+ total_file_size_not_greater_than: "toplam dosya boyutu %{min_size} boyutundan büyük olmalıdır (geçerli boyut %{total_file_size}'dir)"
13
+ total_file_size_not_greater_than_or_equal_to: "toplam dosya boyutu %{min_size} değerinden büyük veya eşit olmalıdır (geçerli boyut %{total_file_size}'dir)"
14
+ total_file_size_not_between: "toplam dosya boyutu %{min_size} ile %{max_size} arasında olmalıdır (geçerli boyut %{total_file_size}'dir)"
10
15
  limit_out_of_range: "toplam miktar aralık dışında"
11
16
  image_metadata_missing: "geçerli bir imaj değil"
12
17
  dimension_min_inclusion: "%{width} x %{height} piksele eşit ya da büyük olmalı"
@@ -7,6 +7,11 @@ uk:
7
7
  file_size_not_greater_than: "розмір файлу має бути більшим ніж %{min_size} (поточний розмір %{file_size})"
8
8
  file_size_not_greater_than_or_equal_to: "розмір файлу має бути більшим або дорівнювати %{min_size} (поточний розмір %{file_size})"
9
9
  file_size_not_between: "розмір файлу має бути від %{min_size} до %{max_size} (поточний розмір %{file_size})"
10
+ total_file_size_not_less_than: "загальний розмір файлу має бути менше %{max_size} (поточний розмір %{total_file_size})"
11
+ total_file_size_not_less_than_or_equal_to: "загальний розмір файлу має бути меншим або дорівнювати %{max_size} (поточний розмір %{total_file_size})"
12
+ total_file_size_not_greater_than: "загальний розмір файлу має бути більшим ніж %{min_size} (поточний розмір %{total_file_size})"
13
+ total_file_size_not_greater_than_or_equal_to: "загальний розмір файлу має бути більшим або дорівнювати %{min_size} (поточний розмір %{total_file_size})"
14
+ total_file_size_not_between: "загальний розмір файлу має бути від %{min_size} до %{max_size} (поточний розмір %{total_file_size})"
10
15
  limit_out_of_range: "кількість файлів більше необхідного"
11
16
  image_metadata_missing: "не є допустимим зображенням"
12
17
  dimension_min_inclusion: "мусить бути більше або дорівнювати %{width} x %{height} пікселям"
@@ -7,6 +7,11 @@ vi:
7
7
  file_size_not_greater_than: "kích thước tệp phải lớn hơn %{min_size} (kích thước hiện tại là %{file_size})"
8
8
  file_size_not_greater_than_or_equal_to: "kích thước tệp phải lớn hơn hoặc bằng %{min_size} (kích thước hiện tại là %{file_size})"
9
9
  file_size_not_between: "kích thước tệp phải nằm trong khoảng từ %{min_size} đến %{max_size} (kích thước hiện tại là %{file_size})"
10
+ total_file_size_not_less_than: "tổng kích thước tệp phải nhỏ hơn %{max_size} (kích thước hiện tại là %{total_file_size})"
11
+ total_file_size_not_less_than_or_equal_to: "tổng kích thước tệp phải nhỏ hơn hoặc bằng %{max_size} (kích thước hiện tại là %{total_file_size})"
12
+ total_file_size_not_greater_than: "tổng kích thước tệp phải lớn hơn %{min_size} (kích thước hiện tại là %{total_file_size})"
13
+ total_file_size_not_greater_than_or_equal_to: "tổng kích thước tệp phải lớn hơn hoặc bằng %{min_size} (kích thước hiện tại là %{total_file_size})"
14
+ total_file_size_not_between: "tổng kích thước tệp phải nằm trong khoảng từ %{min_size} đến %{max_size} (kích thước hiện tại là %{total_file_size})"
10
15
  limit_out_of_range: "tổng số tệp vượt giới hạn"
11
16
  image_metadata_missing: "không phải là ảnh"
12
17
  dimension_min_inclusion: "phải lớn hơn hoặc bằng %{width} x %{height} pixel"
@@ -7,6 +7,11 @@ zh-CN:
7
7
  file_size_not_greater_than: "文件大小必须大于 %{min_size}(当前大小为 %{file_size})"
8
8
  file_size_not_greater_than_or_equal_to: "文件大小必须大于或等于 %{min_size}(当前大小为 %{file_size})"
9
9
  file_size_not_between: "文件大小必须介于 %{min_size} 和 %{max_size} 之间(当前大小为 %{file_size})"
10
+ total_file_size_not_less_than: "总文件大小必须小于 %{max_size}(当前大小为 %{total_file_size})"
11
+ total_file_size_not_less_than_or_equal_to: "文件总大小必须小于或等于 %{max_size}(当前大小为 %{total_file_size})"
12
+ total_file_size_not_greater_than: "总文件大小必须大于 %{min_size}(当前大小为 %{total_file_size})"
13
+ total_file_size_not_greater_than_or_equal_to: "文件总大小必须大于或等于 %{min_size}(当前大小为 %{total_file_size})"
14
+ total_file_size_not_between: "总文件大小必须介于 %{min_size} 和 %{max_size} 之间(当前大小为 %{total_file_size})"
10
15
  limit_out_of_range: "文件数超出限定范围"
11
16
  image_metadata_missing: "不是有效的图像"
12
17
  dimension_min_inclusion: "必须大于或等于 %{width} x %{height} 像素"
@@ -11,16 +11,16 @@ module ActiveStorageValidations
11
11
  ERROR_TYPES = %i[blank].freeze
12
12
 
13
13
  def check_validity!
14
- %i(allow_nil allow_blank).each do |not_authorized_option|
14
+ %i[allow_nil allow_blank].each do |not_authorized_option|
15
15
  if options.include?(not_authorized_option)
16
- raise ArgumentError, "You cannot pass the :#{not_authorized_option} option to this validator"
16
+ raise ArgumentError, "You cannot pass the :#{not_authorized_option} option to the #{self.class.name.split('::').last.underscore}"
17
17
  end
18
18
  end
19
19
  end
20
20
 
21
21
  def validate_each(record, attribute, _value)
22
22
  return if record.send(attribute).attached? &&
23
- !Array.wrap(record.send(attribute)).all? { |file| file.marked_for_destruction? }
23
+ !Array.wrap(record.send(attribute)).all?(&:marked_for_destruction?)
24
24
 
25
25
  errors_options = initialize_error_options(options)
26
26
  add_error(record, attribute, ERROR_TYPES.first, **errors_options)
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'concerns/errorable.rb'
4
+ require_relative 'concerns/symbolizable.rb'
5
+
6
+ module ActiveStorageValidations
7
+ class BaseSizeValidator < ActiveModel::EachValidator # :nodoc:
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
21
+
22
+ def initialize(*args)
23
+ if self.class == BaseSizeValidator
24
+ raise NotImplementedError, 'BaseSizeValidator is an abstract class and cannot be instantiated directly.'
25
+ end
26
+ super
27
+ end
28
+
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
+ private
36
+
37
+ def is_valid?(size, flat_options)
38
+ return false if size < 0
39
+
40
+ if flat_options[:between].present?
41
+ flat_options[:between].include?(size)
42
+ elsif flat_options[:less_than].present?
43
+ size < flat_options[:less_than]
44
+ elsif flat_options[:less_than_or_equal_to].present?
45
+ size <= flat_options[:less_than_or_equal_to]
46
+ elsif flat_options[:greater_than].present?
47
+ size > flat_options[:greater_than]
48
+ elsif flat_options[:greater_than_or_equal_to].present?
49
+ size >= flat_options[:greater_than_or_equal_to]
50
+ end
51
+ end
52
+
53
+ def populate_error_options(errors_options, flat_options)
54
+ errors_options[:min_size] = number_to_human_size(min_size(flat_options))
55
+ errors_options[:max_size] = number_to_human_size(max_size(flat_options))
56
+ end
57
+
58
+ def min_size(flat_options)
59
+ flat_options[:between]&.min || flat_options[:greater_than] || flat_options[:greater_than_or_equal_to]
60
+ end
61
+
62
+ def max_size(flat_options)
63
+ flat_options[:between]&.max || flat_options[:less_than] || flat_options[:less_than_or_equal_to]
64
+ end
65
+ end
66
+ end
@@ -9,7 +9,7 @@ module ActiveStorageValidations
9
9
  active_storage_validations_options = {
10
10
  validator_type: self.class.to_sym,
11
11
  custom_message: (options[:message] if options[:message].present?),
12
- filename: get_filename(file)
12
+ filename: (get_filename(file) unless self.class.to_sym == :total_size)
13
13
  }.compact
14
14
 
15
15
  curated_options.merge(active_storage_validations_options)
@@ -30,7 +30,7 @@ module ActiveStorageValidations
30
30
  return nil unless file
31
31
 
32
32
  case file
33
- when ActiveStorage::Attached then file.blob.filename.to_s
33
+ when ActiveStorage::Attached, ActiveStorage::Attachment then file.blob&.filename&.to_s
34
34
  when Hash then file[:filename]
35
35
  end
36
36
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative 'concerns/active_storageable.rb'
4
4
  require_relative 'concerns/allow_blankable.rb'
5
+ require_relative 'concerns/attachable.rb'
5
6
  require_relative 'concerns/contextable.rb'
6
7
  require_relative 'concerns/messageable.rb'
7
8
  require_relative 'concerns/rspecable.rb'
@@ -9,13 +10,14 @@ require_relative 'concerns/validatable.rb'
9
10
 
10
11
  module ActiveStorageValidations
11
12
  module Matchers
12
- def validate_aspect_ratio_of(name, expected_aspect_ratio)
13
- AspectRatioValidatorMatcher.new(name, expected_aspect_ratio)
13
+ def validate_aspect_ratio_of(attribute_name)
14
+ AspectRatioValidatorMatcher.new(attribute_name)
14
15
  end
15
16
 
16
17
  class AspectRatioValidatorMatcher
17
18
  include ActiveStorageable
18
19
  include AllowBlankable
20
+ include Attachable
19
21
  include Contextable
20
22
  include Messageable
21
23
  include Rspecable
@@ -76,6 +78,7 @@ module ActiveStorageValidations
76
78
 
77
79
  mock_dimensions_for(attach_file, width, height) do
78
80
  validate
81
+ detach_file
79
82
  is_valid?
80
83
  end
81
84
  end
@@ -85,23 +88,11 @@ module ActiveStorageValidations
85
88
 
86
89
  mock_dimensions_for(attach_file, -1, -1) do
87
90
  validate
91
+ detach_file
88
92
  has_an_error_message_which_is_custom_message?
89
93
  end
90
94
  end
91
95
 
92
- def attach_file
93
- @subject.public_send(@attribute_name).attach(dummy_file)
94
- @subject.public_send(@attribute_name)
95
- end
96
-
97
- def dummy_file
98
- {
99
- io: Tempfile.new('Hello world!'),
100
- filename: 'test.png',
101
- content_type: 'image/png'
102
- }
103
- end
104
-
105
96
  def mock_dimensions_for(attachment, width, height)
106
97
  Matchers.mock_metadata(attachment, width, height) do
107
98
  yield