active_storage_validations 1.1.4 → 1.2.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.
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