You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGES.md
+8-1Lines changed: 8 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,13 @@
1
+
- 2.0.4
2
+
- Fix issue when updating a child record through a parent (like: parent_model.update(child_attributes: { image: file })) for Rails >= 8.0.2 (https://github.com/igorkasyanchuk/active_storage_validations/pull/378)
3
+
4
+
- 2.0.3
5
+
- Allow to pass an Array, a splatted Array, or a single string for allowing / rejecting content_type matcher methods (https://github.com/igorkasyanchuk/active_storage_validations/pull/372)
6
+
- Fix issue when an attachment was missing on a blob (https://github.com/igorkasyanchuk/active_storage_validations/pull/373)
7
+
1
8
- 2.0.2
2
9
- Fix undesirable mutation of Marcel::TYPE_EXTS (https://github.com/igorkasyanchuk/active_storage_validations/issues/356)
3
-
- Fix gem loading issue with Marcel custo initialisers (https://github.com/igorkasyanchuk/active_storage_validations/issues/355)
10
+
- Fix gem loading issue with Marcel custom initialisers (https://github.com/igorkasyanchuk/active_storage_validations/issues/355)
4
11
5
12
- 2.0.1
6
13
- Fix for invalid content type validation ([PR #347](https://github.com/igorkasyanchuk/active_storage_validations/pull/347))
[](https://buymeacoffee.com/igorkasyanchuk)
10
11
11
12
Active Storage Validations is a gem that allows you to add validations for Active Storage attributes.
12
13
@@ -53,7 +54,7 @@ $ bundle
53
54
54
55
### Error messages (I18n)
55
56
56
-
Once you have installed the gem, you need to add the gem I18n error messages to your app. See [Internationalization (I18n)](#internationalization-i18n) section for more details.
57
+
Once you have installed the gem, I18n error messages will be added automatically to your app. See [Internationalization (I18n)](#internationalization-i18n) section for more details.
57
58
58
59
### Using image metadata validators
59
60
@@ -71,6 +72,8 @@ Plus, you have to be sure to have the corresponding command-line tool installed
71
72
72
73
To use the video and audio metadata validators (`dimension`, `aspect_ratio`, `processable_file` and `duration`), you will not need to add any gems. However you will need to have the `ffmpeg` command-line tool installed on your system (once again, be sure to have it installed both on your local and in your CI / production environments).
73
74
75
+
If you want some inspiration about how to add `imagemagick`, `libvips` or `ffmpeg` to your docker image, you can check how we do it for the gem CI (https://github.com/igorkasyanchuk/active_storage_validations/blob/master/.github/workflows/main.yml)
76
+
74
77
### Using content type spoofing protection validator option
75
78
76
79
To use the `spoofing_protection` option with the `content_type` validator, you only need to have the UNIX `file` command on your system.
@@ -248,7 +251,7 @@ If you choose to use a content_type 'shorthand' (like `png`), note that it will
Be sure to at least include one the the `extensions`, `parents` or `magic` option, otherwise the content type will not be registered.
254
+
Be sure to at least include one the `extensions`, `parents` or `magic` option, otherwise the content type will not be registered.
252
255
253
256
#### Content type spoofing protection
254
257
@@ -656,65 +659,11 @@ But this major version bump also comes with some breaking changes. Below are the
656
659
657
660
## Internationalization (I18n)
658
661
659
-
Active Storage Validations uses I18n for error messages. Add these keys in your translation files to make them available:
662
+
Active Storage Validations uses I18n for error messages. The error messages are automatically loaded in your Rails app if your language translations are present in the gem.
660
663
661
-
```yml
662
-
en:
663
-
errors:
664
-
messages:
665
-
content_type_invalid:
666
-
one: "has an invalid content type (authorized content type is %{authorized_human_content_types})"
667
-
other: "has an invalid content type (authorized content types are %{authorized_human_content_types})"
668
-
content_type_spoofed:
669
-
one: "has a content type that is not equivalent to the one that is detected through its content (authorized content type is %{authorized_human_content_types})"
670
-
other: "has a content type that is not equivalent to the one that is detected through its content (authorized content types are %{authorized_human_content_types})"
671
-
file_size_not_less_than: "file size must be less than %{max} (current size is %{file_size})"
672
-
file_size_not_less_than_or_equal_to: "file size must be less than or equal to %{max} (current size is %{file_size})"
673
-
file_size_not_greater_than: "file size must be greater than %{min} (current size is %{file_size})"
674
-
file_size_not_greater_than_or_equal_to: "file size must be greater than or equal to %{min} (current size is %{file_size})"
675
-
file_size_not_between: "file size must be between %{min} and %{max} (current size is %{file_size})"
676
-
total_file_size_not_less_than: "total file size must be less than %{max} (current size is %{total_file_size})"
677
-
total_file_size_not_less_than_or_equal_to: "total file size must be less than or equal to %{max} (current size is %{total_file_size})"
678
-
total_file_size_not_greater_than: "total file size must be greater than %{min} (current size is %{total_file_size})"
679
-
total_file_size_not_greater_than_or_equal_to: "total file size must be greater than or equal to %{min} (current size is %{total_file_size})"
680
-
total_file_size_not_between: "total file size must be between %{min} and %{max} (current size is %{total_file_size})"
681
-
duration_not_less_than: "duration must be less than %{max} (current duration is %{duration})"
682
-
duration_not_less_than_or_equal_to: "duration must be less than or equal to %{max} (current duration is %{duration})"
683
-
duration_not_greater_than: "duration must be greater than %{min} (current duration is %{duration})"
684
-
duration_not_greater_than_or_equal_to: "duration must be greater than or equal to %{min} (current duration is %{duration})"
685
-
duration_not_between: "duration must be between %{min} and %{max} (current duration is %{duration})"
686
-
limit_out_of_range:
687
-
zero: "no files attached (must have between %{min} and %{max} files)"
688
-
one: "only 1 file attached (must have between %{min} and %{max} files)"
689
-
other: "total number of files must be between %{min} and %{max} files (there are %{count} files attached)"
690
-
limit_min_not_reached:
691
-
zero: "no files attached (must have at least %{min} files)"
692
-
one: "only 1 file attached (must have at least %{min} files)"
693
-
other: "%{count} files attached (must have at least %{min} files)"
694
-
limit_max_exceeded:
695
-
zero: "no files attached (maximum is %{max} files)"
696
-
one: "too many files attached (maximum is %{max} files, got %{count})"
697
-
other: "too many files attached (maximum is %{max} files, got %{count})"
698
-
media_metadata_missing: "is not a valid media file"
699
-
dimension_min_not_included_in: "must be greater than or equal to %{width} x %{height} pixel"
700
-
dimension_max_not_included_in: "must be less than or equal to %{width} x %{height} pixel"
701
-
dimension_width_not_included_in: "width is not included between %{min} and %{max} pixel"
702
-
dimension_height_not_included_in: "height is not included between %{min} and %{max} pixel"
703
-
dimension_width_not_greater_than_or_equal_to: "width must be greater than or equal to %{length} pixel"
704
-
dimension_height_not_greater_than_or_equal_to: "height must be greater than or equal to %{length} pixel"
705
-
dimension_width_not_less_than_or_equal_to: "width must be less than or equal to %{length} pixel"
706
-
dimension_height_not_less_than_or_equal_to: "height must be less than or equal to %{length} pixel"
707
-
dimension_width_not_equal_to: "width must be equal to %{length} pixel"
708
-
dimension_height_not_equal_to: "height must be equal to %{length} pixel"
709
-
aspect_ratio_not_square: "must be square (current file is %{width}x%{height}px)"
710
-
aspect_ratio_not_portrait: "must be portrait (current file is %{width}x%{height}px)"
711
-
aspect_ratio_not_landscape: "must be landscape (current file is %{width}x%{height}px)"
712
-
aspect_ratio_not_x_y: "must be %{authorized_aspect_ratios} (current file is %{width}x%{height}px)"
713
-
aspect_ratio_invalid: "has an invalid aspect ratio (valid aspect ratios are %{authorized_aspect_ratios})"
714
-
file_not_processable: "is not identified as a valid media file"
715
-
```
664
+
Translation files are available [here](https://github.com/igorkasyanchuk/active_storage_validations/tree/master/config/locales). We currently have translations for `da`, `de`, `en`, `en-GB`, `es`, `fr`, `it`, `ja`, `nl`, `pl`, `pt-BR`, `ru`, `sv`, `tr`, `uk`, `vi` and `zh-CN`. Feel free to drop a PR to add your language ✌️.
716
665
717
-
Other translation files are available [here](https://github.com/igorkasyanchuk/active_storage_validations/tree/master/config/locales).
666
+
If you wish to customize the error messages, just copy, paste and update the translation files into your application locales.
718
667
719
668
## Test matchers
720
669
@@ -760,8 +709,8 @@ describe User do
760
709
761
710
# content_type:
762
711
# #allowing, #rejecting
763
-
it { is_expected.to validate_content_type_of(:avatar).allowing('image/png', 'image/gif') }
764
-
it { is_expected.to validate_content_type_of(:avatar).rejecting('text/plain', 'text/xml') }
712
+
it { is_expected.to validate_content_type_of(:avatar).allowing('image/png', 'image/gif') } # possible to use an Array or *splatted array
713
+
it { is_expected.to validate_content_type_of(:avatar).rejecting('text/plain', 'text/xml') } # possible to use an Array or *splatted array
[](https://buymeacoffee.com/igorkasyanchuk)
one: "has an invalid content type (authorized content type is %{authorized_human_content_types})"
6
+
other: "has an invalid content type (authorized content types are %{authorized_human_content_types})"
7
+
content_type_spoofed:
8
+
one: "has a content type that is not equivalent to the one that is detected through its content (authorized content type is %{authorized_human_content_types})"
9
+
other: "has a content type that is not equivalent to the one that is detected through its content (authorized content types are %{authorized_human_content_types})"
10
+
file_size_not_less_than: "file size must be less than %{max} (current size is %{file_size})"
11
+
file_size_not_less_than_or_equal_to: "file size must be less than or equal to %{max} (current size is %{file_size})"
12
+
file_size_not_greater_than: "file size must be greater than %{min} (current size is %{file_size})"
13
+
file_size_not_greater_than_or_equal_to: "file size must be greater than or equal to %{min} (current size is %{file_size})"
14
+
file_size_not_between: "file size must be between %{min} and %{max} (current size is %{file_size})"
15
+
total_file_size_not_less_than: "total file size must be less than %{max} (current size is %{total_file_size})"
16
+
total_file_size_not_less_than_or_equal_to: "total file size must be less than or equal to %{max} (current size is %{total_file_size})"
17
+
total_file_size_not_greater_than: "total file size must be greater than %{min} (current size is %{total_file_size})"
18
+
total_file_size_not_greater_than_or_equal_to: "total file size must be greater than or equal to %{min} (current size is %{total_file_size})"
19
+
total_file_size_not_between: "total file size must be between %{min} and %{max} (current size is %{total_file_size})"
20
+
duration_not_less_than: "duration must be less than %{max} (current duration is %{duration})"
21
+
duration_not_less_than_or_equal_to: "duration must be less than or equal to %{max} (current duration is %{duration})"
22
+
duration_not_greater_than: "duration must be greater than %{min} (current duration is %{duration})"
23
+
duration_not_greater_than_or_equal_to: "duration must be greater than or equal to %{min} (current duration is %{duration})"
24
+
duration_not_between: "duration must be between %{min} and %{max} (current duration is %{duration})"
25
+
limit_out_of_range:
26
+
zero: "no files attached (must have between %{min} and %{max} files)"
27
+
one: "only 1 file attached (must have between %{min} and %{max} files)"
28
+
other: "total number of files must be between %{min} and %{max} files (there are %{count} files attached)"
29
+
limit_min_not_reached:
30
+
zero: "no files attached (must have at least %{min} files)"
31
+
one: "only 1 file attached (must have at least %{min} files)"
32
+
other: "%{count} files attached (must have at least %{min} files)"
33
+
limit_max_exceeded:
34
+
zero: "no files attached (maximum is %{max} files)"
35
+
one: "too many files attached (maximum is %{max} files, got %{count})"
36
+
other: "too many files attached (maximum is %{max} files, got %{count})"
37
+
attachment_missing: "is missing its attachment"
38
+
media_metadata_missing: "is not a valid media file"
39
+
dimension_min_not_included_in: "must be greater than or equal to %{width} x %{height} pixel"
40
+
dimension_max_not_included_in: "must be less than or equal to %{width} x %{height} pixel"
41
+
dimension_width_not_included_in: "width is not included between %{min} and %{max} pixel"
42
+
dimension_height_not_included_in: "height is not included between %{min} and %{max} pixel"
43
+
dimension_width_not_greater_than_or_equal_to: "width must be greater than or equal to %{length} pixel"
44
+
dimension_height_not_greater_than_or_equal_to: "height must be greater than or equal to %{length} pixel"
45
+
dimension_width_not_less_than_or_equal_to: "width must be less than or equal to %{length} pixel"
46
+
dimension_height_not_less_than_or_equal_to: "height must be less than or equal to %{length} pixel"
47
+
dimension_width_not_equal_to: "width must be equal to %{length} pixel"
48
+
dimension_height_not_equal_to: "height must be equal to %{length} pixel"
49
+
aspect_ratio_not_square: "must be square (current file is %{width}x%{height}px)"
50
+
aspect_ratio_not_portrait: "must be portrait (current file is %{width}x%{height}px)"
51
+
aspect_ratio_not_landscape: "must be landscape (current file is %{width}x%{height}px)"
52
+
aspect_ratio_not_x_y: "must be %{authorized_aspect_ratios} (current file is %{width}x%{height}px)"
53
+
aspect_ratio_invalid: "has an invalid aspect ratio (valid aspect ratios are %{authorized_aspect_ratios})"
54
+
file_not_processable: "is not identified as a valid media file"
0 commit comments