active_storage_validations 1.1.3 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +133 -69
  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/aspect_ratio_validator.rb +47 -22
  20. data/lib/active_storage_validations/attached_validator.rb +12 -3
  21. data/lib/active_storage_validations/base_size_validator.rb +66 -0
  22. data/lib/active_storage_validations/concerns/errorable.rb +38 -0
  23. data/lib/active_storage_validations/concerns/symbolizable.rb +8 -6
  24. data/lib/active_storage_validations/content_type_validator.rb +41 -6
  25. data/lib/active_storage_validations/dimension_validator.rb +15 -15
  26. data/lib/active_storage_validations/limit_validator.rb +44 -7
  27. data/lib/active_storage_validations/matchers/aspect_ratio_validator_matcher.rb +119 -0
  28. data/lib/active_storage_validations/matchers/attached_validator_matcher.rb +25 -36
  29. data/lib/active_storage_validations/matchers/base_size_validator_matcher.rb +134 -0
  30. data/lib/active_storage_validations/matchers/concerns/active_storageable.rb +17 -0
  31. data/lib/active_storage_validations/matchers/concerns/allow_blankable.rb +26 -0
  32. data/lib/active_storage_validations/matchers/concerns/attachable.rb +48 -0
  33. data/lib/active_storage_validations/matchers/concerns/contextable.rb +47 -0
  34. data/lib/active_storage_validations/matchers/concerns/messageable.rb +26 -0
  35. data/lib/active_storage_validations/matchers/concerns/rspecable.rb +25 -0
  36. data/lib/active_storage_validations/matchers/concerns/validatable.rb +11 -10
  37. data/lib/active_storage_validations/matchers/content_type_validator_matcher.rb +44 -27
  38. data/lib/active_storage_validations/matchers/dimension_validator_matcher.rb +67 -59
  39. data/lib/active_storage_validations/matchers/processable_image_validator_matcher.rb +78 -0
  40. data/lib/active_storage_validations/matchers/size_validator_matcher.rb +8 -126
  41. data/lib/active_storage_validations/matchers/total_size_validator_matcher.rb +40 -0
  42. data/lib/active_storage_validations/matchers.rb +3 -0
  43. data/lib/active_storage_validations/metadata.rb +60 -28
  44. data/lib/active_storage_validations/processable_image_validator.rb +14 -5
  45. data/lib/active_storage_validations/size_validator.rb +7 -51
  46. data/lib/active_storage_validations/total_size_validator.rb +49 -0
  47. data/lib/active_storage_validations/version.rb +1 -1
  48. data/lib/active_storage_validations.rb +3 -2
  49. metadata +38 -39
  50. data/lib/active_storage_validations/error_handler.rb +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1ee85f42558858c115d91d107a0b67f6088d65b4cbc1ec8461f4f5baf230a025
4
- data.tar.gz: 4cf3fdb1bde0e805d22ad7d7d81d43cf5b378e06bde5443d938d1e390deee816
3
+ metadata.gz: c4e1690b53c320459f3dcd874f52680d67b8e1f1b6dc68eccff486c5a664695a
4
+ data.tar.gz: 5d1a163646400c3ee50feff6c2c847408fa8c54f42457d9493ddfa0c4f900ab0
5
5
  SHA512:
6
- metadata.gz: 9c3a532221860176a87f042126b7a068425d2efca7ec908393691ae807af36e55b10d38180f8226dd73c1da0cff9f7dc5d1408ac1049ccbef58033ce9fdca48c
7
- data.tar.gz: 469f3406a95dc8d0466d475d1cabc5b5658e813430728593140ce78b96892d0837da075f83d2901967b258f7ff57cf830390401737cb2f739b0bcd6c13d16aa3
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,27 +63,32 @@ 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. In order to infer the correct mime type from the symbol, the types must be registered with `Marcel::EXTENSIONS` (`MimeMagic::EXTENSIONS` for Rails <= 6.1.3).
72
+ - Content type validation using symbols or regex.
72
73
 
73
74
  ```ruby
74
75
  class User < ApplicationRecord
75
76
  has_one_attached :avatar
76
77
  has_many_attached :photos
77
78
 
78
- validates :avatar, attached: true, content_type: :png # Marcel::Magic.by_extension(:png).to_s => 'image/png'
79
- # Rails <= 6.1.3; MimeMagic.by_extension(:png).to_s => 'image/png'
79
+ validates :avatar, attached: true, content_type: :png
80
80
  # or
81
81
  validates :photos, attached: true, content_type: [:png, :jpg, :jpeg]
82
82
  # or
83
83
  validates :avatar, content_type: /\Aimage\/.*\z/
84
84
  end
85
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
+ ```
86
92
 
87
93
  - Dimension validation with `width`, `height` and `in`.
88
94
 
@@ -154,18 +160,23 @@ en:
154
160
  file_size_not_greater_than: "file size must be greater than %{min_size} (current size is %{file_size})"
155
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})"
156
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})"
157
168
  limit_out_of_range: "total number is out of range"
158
169
  image_metadata_missing: "is not a valid image"
159
- dimension_min_inclusion: "must be greater than or equal to %{width} x %{height} pixel."
160
- dimension_max_inclusion: "must be less than or equal to %{width} x %{height} pixel."
161
- dimension_width_inclusion: "width is not included between %{min} and %{max} pixel."
162
- dimension_height_inclusion: "height is not included between %{min} and %{max} pixel."
163
- dimension_width_greater_than_or_equal_to: "width must be greater than or equal to %{length} pixel."
164
- dimension_height_greater_than_or_equal_to: "height must be greater than or equal to %{length} pixel."
165
- dimension_width_less_than_or_equal_to: "width must be less than or equal to %{length} pixel."
166
- dimension_height_less_than_or_equal_to: "height must be less than or equal to %{length} pixel."
167
- dimension_width_equal_to: "width must be equal to %{length} pixel."
168
- 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"
169
180
  aspect_ratio_not_square: "must be a square image"
170
181
  aspect_ratio_not_portrait: "must be a portrait image"
171
182
  aspect_ratio_not_landscape: "must be a landscape image"
@@ -174,12 +185,24 @@ en:
174
185
  image_not_processable: "is not a valid image"
175
186
  ```
176
187
 
177
- In some cases, Active Storage Validations provides variables to help you customize messages:
188
+ In several cases, Active Storage Validations provides variables to help you customize messages:
189
+
190
+ ### Aspect ratio
191
+ The keys starting with `aspect_ratio_` support two variables that you can use:
192
+ - `aspect_ratio` containing the expected aspect ratio, especially useful for custom aspect ratio
193
+ - `filename` containing the current file name
194
+
195
+ For example :
196
+
197
+ ```yml
198
+ aspect_ratio_is_not: "must be a %{aspect_ratio} image"
199
+ ```
178
200
 
179
201
  ### Content type
180
- The `content_type_invalid` key has two variables that you can use:
202
+ The `content_type_invalid` key has three variables that you can use:
181
203
  - `content_type` containing the content type of the sent file
182
204
  - `authorized_types` containing the list of authorized content types
205
+ - `filename` containing the current file name
183
206
 
184
207
  For example :
185
208
 
@@ -187,22 +210,27 @@ For example :
187
210
  content_type_invalid: "has an invalid content type : %{content_type}, authorized types are %{authorized_types}"
188
211
  ```
189
212
 
190
- ### Number of files
191
- The `limit_out_of_range` key supports two variables that you can use:
192
- - `min` containing the minimum number of files
193
- - `max` containing the maximum number of files
213
+ ### Dimension
214
+ The keys starting with `dimension_` support six variables that you can use:
215
+ - `min` containing the minimum width or height allowed
216
+ - `max` containing the maximum width or height allowed
217
+ - `width` containing the minimum or maximum width allowed
218
+ - `height` containing the minimum or maximum width allowed
219
+ - `length` containing the exact width or height allowed
220
+ - `filename` containing the current file name
194
221
 
195
222
  For example :
196
223
 
197
224
  ```yml
198
- limit_out_of_range: "total number is out of range. range: [%{min}, %{max}]"
225
+ dimension_min_inclusion: "must be greater than or equal to %{width} x %{height} pixel."
199
226
  ```
200
227
 
201
228
  ### File size
202
- The keys starting with `file_size_not_` support three variables that you can use:
229
+ The keys starting with `file_size_not_` support four variables that you can use:
203
230
  - `file_size` containing the current file size
204
231
  - `min` containing the minimum file size
205
- - `max` containing the maxmimum file size
232
+ - `max` containing the maximum file size
233
+ - `filename` containing the current file name
206
234
 
207
235
  For example :
208
236
 
@@ -210,14 +238,37 @@ For example :
210
238
  file_size_not_between: "file size must be between %{min_size} and %{max_size} (current size is %{file_size})"
211
239
  ```
212
240
 
213
- ### Aspect ratio
214
- The keys starting with `aspect_ratio_` support one variable that you can use:
215
- - `aspect_ratio` containing the expected aspect ratio, especially usefull for custom aspect ratio
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
216
246
 
217
247
  For example :
218
248
 
219
249
  ```yml
220
- aspect_ratio_is_not: "must be a %{aspect_ratio} image"
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
+
253
+ ### Number of files
254
+ The `limit_out_of_range` key supports two variables that you can use:
255
+ - `min` containing the minimum number of files
256
+ - `max` containing the maximum number of files
257
+
258
+ For example :
259
+
260
+ ```yml
261
+ limit_out_of_range: "total number is out of range. range: [%{min}, %{max}]"
262
+ ```
263
+
264
+ ### Processable image
265
+ The `image_not_processable` key supports one variable that you can use:
266
+ - `filename` containing the current file name
267
+
268
+ For example :
269
+
270
+ ```yml
271
+ image_not_processable: "is not a valid image (file: %{filename})"
221
272
  ```
222
273
 
223
274
  ## Installation
@@ -225,7 +276,6 @@ aspect_ratio_is_not: "must be a %{aspect_ratio} image"
225
276
  Add this line to your application's Gemfile:
226
277
 
227
278
  ```ruby
228
- # Rails 5.2 and Rails 6
229
279
  gem 'active_storage_validations'
230
280
 
231
281
  # Optional, to use :dimension validator or :aspect_ratio validator
@@ -247,7 +297,8 @@ Very simple example of validation with file attached, content type check and cus
247
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)
248
298
 
249
299
  ## Test matchers
250
- Provides RSpec-compatible and Minitest-compatible matchers for testing the validators.
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.
251
302
 
252
303
  ### RSpec
253
304
 
@@ -265,38 +316,76 @@ RSpec.configure do |config|
265
316
  end
266
317
  ```
267
318
 
268
- Example (Note that the options are chainable):
319
+ Matcher methods available:
269
320
 
270
321
  ```ruby
271
322
  describe User do
323
+ # aspect_ratio:
324
+ # #allowing, #rejecting
325
+ it { is_expected.to validate_aspect_ratio_of(:avatar).allowing(:square) }
326
+ it { is_expected.to validate_aspect_ratio_of(:avatar).rejecting(:portrait) }
327
+
328
+ # attached
272
329
  it { is_expected.to validate_attached_of(:avatar) }
273
- it { is_expected.to validate_attached_of(:avatar).with_message('must not be blank') }
274
330
 
331
+ # processable_image
332
+ it { is_expected.to validate_processable_image_of(:avatar) }
333
+
334
+ # content_type:
335
+ # #allowing, #rejecting
275
336
  it { is_expected.to validate_content_type_of(:avatar).allowing('image/png', 'image/gif') }
276
337
  it { is_expected.to validate_content_type_of(:avatar).rejecting('text/plain', 'text/xml') }
277
- it { is_expected.to validate_content_type_of(:avatar).rejecting('text/plain', 'text/xml').with_message("must be an authorized type") }
278
338
 
339
+ # dimension:
340
+ # #width, #height, #width_min, #height_min, #width_max, #height_max, #width_between, #height_between
279
341
  it { is_expected.to validate_dimensions_of(:avatar).width(250) }
280
342
  it { is_expected.to validate_dimensions_of(:avatar).height(200) }
281
- it { is_expected.to validate_dimensions_of(:avatar).width(250).height(200).with_message('Invalid dimensions.') }
282
343
  it { is_expected.to validate_dimensions_of(:avatar).width_min(200) }
283
- it { is_expected.to validate_dimensions_of(:avatar).width_max(500) }
284
344
  it { is_expected.to validate_dimensions_of(:avatar).height_min(100) }
345
+ it { is_expected.to validate_dimensions_of(:avatar).width_max(500) }
285
346
  it { is_expected.to validate_dimensions_of(:avatar).height_max(300) }
286
347
  it { is_expected.to validate_dimensions_of(:avatar).width_between(200..500) }
287
348
  it { is_expected.to validate_dimensions_of(:avatar).height_between(100..300) }
288
349
 
350
+ # size:
351
+ # #less_than, #less_than_or_equal_to, #greater_than, #greater_than_or_equal_to, #between
289
352
  it { is_expected.to validate_size_of(:avatar).less_than(50.kilobytes) }
290
353
  it { is_expected.to validate_size_of(:avatar).less_than_or_equal_to(50.kilobytes) }
291
354
  it { is_expected.to validate_size_of(:avatar).greater_than(1.kilobyte) }
292
- it { is_expected.to validate_size_of(:avatar).greater_than(1.kilobyte).with_message('is not in required file size range') }
293
355
  it { is_expected.to validate_size_of(:avatar).greater_than_or_equal_to(1.kilobyte) }
294
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) }
365
+ end
366
+ ```
367
+ (Note that matcher methods are chainable)
368
+
369
+ All matchers can currently be customized with Rails validation options:
370
+
371
+ ```ruby
372
+ describe User do
373
+ # :allow_blank
374
+ it { is_expected.to validate_attached_of(:avatar).allow_blank }
375
+
376
+ # :on
377
+ it { is_expected.to validate_attached_of(:avatar).on(:update) }
378
+ it { is_expected.to validate_attached_of(:avatar).on(%i[update custom]) }
379
+
380
+ # :message
381
+ it { is_expected.to validate_dimensions_of(:avatar).width(250).with_message('Invalid dimensions.') }
295
382
  end
296
383
  ```
297
384
 
298
385
  ### Minitest
299
- To use the following syntax, make sure you have the [shoulda-context](https://github.com/thoughtbot/shoulda-context) gem up and running. To make use of the matchers you need to require the matchers:
386
+ To use the matchers, make sure you have the [shoulda-context](https://github.com/thoughtbot/shoulda-context) gem up and running.
387
+
388
+ You need to require the matchers:
300
389
 
301
390
  ```ruby
302
391
  require 'active_storage_validations/matchers'
@@ -310,35 +399,7 @@ class ActiveSupport::TestCase
310
399
  end
311
400
  ```
312
401
 
313
- Example (Note that the options are chainable):
314
-
315
- ```ruby
316
- class UserTest < ActiveSupport::TestCase
317
- should validate_attached_of(:avatar)
318
- should validate_attached_of(:avatar).with_message('must not be blank')
319
-
320
- should validate_content_type_of(:avatar).allowing('image/png', 'image/gif')
321
- should validate_content_type_of(:avatar).rejecting('text/plain', 'text/xml')
322
- should validate_content_type_of(:avatar).rejecting('text/plain', 'text/xml').with_message("must be an authorized type")
323
-
324
- should validate_dimensions_of(:avatar).width(250)
325
- should validate_dimensions_of(:avatar).height(200)
326
- should validate_dimensions_of(:avatar).width(250).height(200).with_message('Invalid dimensions.')
327
- should validate_dimensions_of(:avatar).width_min(200)
328
- should validate_dimensions_of(:avatar).width_max(500)
329
- should validate_dimensions_of(:avatar).height_min(100)
330
- should validate_dimensions_of(:avatar).height_max(300)
331
- should validate_dimensions_of(:avatar).width_between(200..500)
332
- should validate_dimensions_of(:avatar).height_between(100..300)
333
-
334
- should validate_size_of(:avatar).less_than(50.kilobytes)
335
- should validate_size_of(:avatar).less_than_or_equal_to(50.kilobytes)
336
- should validate_size_of(:avatar).greater_than(1.kilobyte)
337
- should validate_size_of(:avatar).greater_than(1.kilobyte).with_message('is not in required file size range')
338
- should validate_size_of(:avatar).greater_than_or_equal_to(1.kilobyte)
339
- should validate_size_of(:avatar).between(100..500.kilobytes)
340
- end
341
- ```
402
+ Then you can use the matchers with the syntax specified in the RSpec section, just use `should validate_method` instead of `it { is_expected_to validate_method }` as specified in the [shoulda-context](https://github.com/thoughtbot/shoulda-context) gem.
342
403
 
343
404
  ## Todo
344
405
 
@@ -350,7 +411,7 @@ end
350
411
 
351
412
  To run tests in root folder of gem:
352
413
 
353
- * `BUNDLE_GEMFILE=gemfiles/rails_6_1.gemfile bundle exec rake test` to run for Rails 6.1
414
+ * `BUNDLE_GEMFILE=gemfiles/rails_6_1_3_1.gemfile bundle exec rake test` to run for Rails 6.1
354
415
  * `BUNDLE_GEMFILE=gemfiles/rails_7_0.gemfile bundle exec rake test` to run for Rails 7.0
355
416
  * `BUNDLE_GEMFILE=gemfiles/rails_7_1.gemfile bundle exec rake test` to run for Rails 7.0
356
417
  * `BUNDLE_GEMFILE=gemfiles/rails_next.gemfile bundle exec rake test` to run for Rails main branch
@@ -358,11 +419,11 @@ To run tests in root folder of gem:
358
419
  Snippet to run in console:
359
420
 
360
421
  ```bash
361
- BUNDLE_GEMFILE=gemfiles/rails_6_1.gemfile bundle
422
+ BUNDLE_GEMFILE=gemfiles/rails_6_1_3_1.gemfile bundle
362
423
  BUNDLE_GEMFILE=gemfiles/rails_7_0.gemfile bundle
363
424
  BUNDLE_GEMFILE=gemfiles/rails_7_1.gemfile bundle
364
425
  BUNDLE_GEMFILE=gemfiles/rails_next.gemfile bundle
365
- BUNDLE_GEMFILE=gemfiles/rails_6_1.gemfile bundle exec rake test
426
+ BUNDLE_GEMFILE=gemfiles/rails_6_1_3_1.gemfile bundle exec rake test
366
427
  BUNDLE_GEMFILE=gemfiles/rails_7_0.gemfile bundle exec rake test
367
428
  BUNDLE_GEMFILE=gemfiles/rails_7_1.gemfile bundle exec rake test
368
429
  BUNDLE_GEMFILE=gemfiles/rails_next.gemfile bundle exec rake test
@@ -431,7 +492,6 @@ You are welcome to contribute.
431
492
  - https://github.com/vietqhoang
432
493
  - https://github.com/kemenaran
433
494
  - https://github.com/jrmhaig
434
- - https://github.com/tagliala
435
495
  - https://github.com/evedovelli
436
496
  - https://github.com/JuanVqz
437
497
  - https://github.com/luiseugenio
@@ -454,6 +514,10 @@ You are welcome to contribute.
454
514
  - https://github.com/tagliala
455
515
  - https://github.com/ocarreterom
456
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
457
521
 
458
522
 
459
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} 像素"