active_storage_validations 0.8.7 → 0.9.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8ee7d6623af014086158c960b7ef7408f4cf7527536f57539765351357160189
4
- data.tar.gz: 6819ee596bd09560ca801fade1006bfbe4bf03b820b7ca1b0f84eafe0bb47ac1
3
+ metadata.gz: 6e8b30d036f53b6e00b209c9fe9a34339ff23aa35b789da9585df7fee6c8dfad
4
+ data.tar.gz: 0655072452aa29e24bcea5abb01e6b72bf6ddee6f2646d92eb8b13dbaeff128f
5
5
  SHA512:
6
- metadata.gz: c1a79fa7e8825320b308f8a689b3b09763072ec8093c5fc1f43e4686dad3dd05b4d345ce8d62149b23865b5c215b90dcdd68b292ea4ccef26456e752a35aad5a
7
- data.tar.gz: 69517cf6f0d5a5c64c39416945f06bb31ccb6c5b1c0288d883005184c96e353d44a3f9479767783bd9aae856ee2157a6ffdde48ebdb6abbf23a5f4972fd8f3b0
6
+ metadata.gz: 8df0893d2048e22d55660f590a747d55b2fff2595bae0f7da8b9151079d2c87e7d09a5e3059529a9fd9ef1231e44b4e9c610d3d22c9da5bfc8e49eb3aa0d25ca
7
+ data.tar.gz: a55c3ba3ff97b5478061fc8a8307127231dbbbb64f49fdcaccea85e6c896e48e777b30e09c97d44b9d84d61b8b5c4ef6abdb843171120b1ae739b38ebf916fb2
data/README.md CHANGED
@@ -1,11 +1,9 @@
1
1
  # Active Storage Validations
2
2
 
3
- If you are using `active_storage` gem and you want to add simple validations for it, like presence or content_type you need to write a custom valiation method.
3
+ If you are using `active_storage` gem and you want to add simple validations for it, like presence or content_type you need to write a custom validation method.
4
4
 
5
5
  This gems doing it for you. Just use `attached: true` or `content_type: 'image/png'` validation.
6
6
 
7
- [![Build Status](https://travis-ci.org/igorkasyanchuk/active_storage_validations.svg?branch=master)](https://travis-ci.org/igorkasyanchuk/active_storage_validations)
8
-
9
7
  ## What it can do
10
8
 
11
9
  * validates if file(s) attached
@@ -117,7 +115,7 @@ end
117
115
 
118
116
  ## Internationalization (I18n)
119
117
 
120
- Active Storage Validations use I18n for errors messages. For this add there keys in your translation file:
118
+ Active Storage Validations uses I18n for error messages. For this, add these keys in your translation file:
121
119
 
122
120
  ```yml
123
121
  en:
@@ -137,19 +135,18 @@ en:
137
135
  dimension_height_less_than_or_equal_to: "height must be less than or equal to %{length} pixel."
138
136
  dimension_width_equal_to: "width must be equal to %{length} pixel."
139
137
  dimension_height_equal_to: "height must be equal to %{length} pixel."
140
- aspect_ratio_not_square: "doesn't a square image"
141
- aspect_ratio_not_portrait: "doesn't contain a portrait image"
142
- aspect_ratio_not_landscape: "doesn't contain a landscape image"
143
- aspect_ratio_is_not: "doesn't contain aspect ratio of %{aspect_ratio}"
138
+ aspect_ratio_not_square: "must be a square image"
139
+ aspect_ratio_not_portrait: "must be a portrait image"
140
+ aspect_ratio_not_landscape: "must be a landscape image"
141
+ aspect_ratio_is_not: "must have an aspect ratio of %{aspect_ratio}"
144
142
  aspect_ratio_unknown: "has an unknown aspect ratio"
145
-
146
143
  ```
147
144
 
148
- In some cases Active Storage Validations provides variables to help you customize messages:
145
+ In some cases, Active Storage Validations provides variables to help you customize messages:
149
146
 
150
- The "content_type_invalid" key has two variables that you can use, a variable named "content_type" containing the content type of the send file and a variable named "authorized_type" containing the list of authorized content types.
147
+ The "content_type_invalid" key has two variables that you can use, a variable named "content_type" containing the content type of the send file and a variable named "authorized_types" containing the list of authorized content types.
151
148
 
152
- It's variables are not used by default to leave the choice to the user.
149
+ The variables are not used by default to leave the choice to the user.
153
150
 
154
151
  For example :
155
152
 
@@ -194,7 +191,7 @@ Provides RSpec-compatible and Minitest-compatible matchers for testing the valid
194
191
 
195
192
  ### RSpec
196
193
 
197
- In spec_helper.rb, you'll need to require the matchers:
194
+ In `spec_helper.rb`, you'll need to require the matchers:
198
195
 
199
196
  ```ruby
200
197
  require 'active_storage_validations/matchers'
@@ -209,7 +206,7 @@ end
209
206
  ```
210
207
 
211
208
  Example (Note that the options are chainable):
212
-
209
+
213
210
  ```ruby
214
211
  describe User do
215
212
  it { is_expected.to validate_attached_of(:avatar) }
@@ -243,7 +240,7 @@ require 'active_storage_validations/matchers'
243
240
 
244
241
  And _extend_ the module:
245
242
 
246
- ```bash
243
+ ```ruby
247
244
  class ActiveSupport::TestCase
248
245
  extend ActiveStorageValidations::Matchers
249
246
  end
@@ -281,27 +278,26 @@ end
281
278
  * verify how it works with direct upload
282
279
  * better error message when content_size is invalid
283
280
  * add more translations
284
- * add aspect ratio validation
285
281
 
286
282
  ## Tests & Contributing
287
283
 
288
284
  To run tests in root folder of gem:
289
285
 
290
286
  * `BUNDLE_GEMFILE=gemfiles/rails_5_2.gemfile bundle exec rake test` to run for Rails 5.2
291
- * `BUNDLE_GEMFILE=gemfiles/rails_6.0.gemfile bundle exec rake test` to run for Rails 6.0
292
-
293
- To play with app `cd test/dummy` and `rails s -b 0.0.0.0` (before `rails db:migrate`).
287
+ * `BUNDLE_GEMFILE=gemfiles/rails_6_0.gemfile bundle exec rake test` to run for Rails 6.0
288
+ * `BUNDLE_GEMFILE=gemfiles/rails_6_1.gemfile bundle exec rake test` to run for Rails 6.1
294
289
 
295
290
  ## Known issues
296
291
 
297
292
  - There is an issue in Rails which it possible to get if you have added a validation and generating for example an image preview of attachments. It can be fixed with this:
298
293
 
299
- ```
294
+ ```erb
300
295
  <% if @user.avatar.attached? && @user.avatar.attachment.blob.present? && @user.avatar.attachment.blob.persisted? %>
301
296
  <%= image_tag @user.avatar %>
302
297
  <% end %>
303
298
  ```
304
- This is Rails issue. And according to commits it will be fixed in Rails 6.
299
+
300
+ This is a Rails issue, and is fixed in Rails 6.
305
301
 
306
302
  ## Contributing
307
303
  You are welcome to contribute.
@@ -327,6 +323,15 @@ You are welcome to contribute.
327
323
  - https://github.com/giovannibonetti
328
324
  - https://github.com/dlepage
329
325
  - https://github.com/StefSchenkelaars
326
+ - https://github.com/willnet
327
+ - https://github.com/mohanklein
328
+ - https://github.com/High5Apps
329
+ - https://github.com/mschnitzer
330
+ - https://github.com/sinankeskin
331
+ - https://github.com/alejandrodevs
332
+ - https://github.com/molfar
333
+ - https://github.com/connorshea
334
+ - https://github.com/yshmarov
330
335
 
331
336
  ## License
332
337
 
@@ -2,16 +2,16 @@ de:
2
2
  errors:
3
3
  messages:
4
4
  content_type_invalid: "hat einen ungültigen Dateityp"
5
- file_size_out_of_range: "Dateigröße von %{file_size} ist außerhalb des erlaubten Bereichs"
5
+ file_size_out_of_range: "Dateigröße %{file_size} liegt nicht im erlaubten Bereich"
6
6
  limit_out_of_range: "Anzahl ist außerhalb des gültigen Bereichs"
7
- image_metadata_missing: "ist nicht ein gültigen Bild"
7
+ image_metadata_missing: "ist kein gültiges Bild"
8
8
  dimension_min_inclusion: "muss größer oder gleich %{width} x %{height} Pixel sein"
9
9
  dimension_max_inclusion: "muss kleiner oder gleich %{width} x %{height} Pixel sein"
10
- dimension_width_inclusion: "Breite ist nicht zwischen %{min} und %{max} Pixel enthalten"
11
- dimension_height_inclusion: "Höhe ist nicht zwischen %{min} und %{max} Pixel enthalten"
12
- dimension_width_greater_than_or_equal_to: "Breite muss größer oder gleich %{length} Pixel sein"
13
- dimension_height_greater_than_or_equal_to: "Höhe muss größer oder gleich %{length} Pixel sein"
10
+ dimension_width_inclusion: "Bildbreite muss zwischen %{min} und %{max} Pixel liegen"
11
+ dimension_height_inclusion: "Bildhöhe muss zwischen %{min} und %{max} Pixel liegen"
12
+ dimension_width_greater_than_or_equal_to: "Bildbreite muss größer oder gleich %{length} Pixel sein"
13
+ dimension_height_greater_than_or_equal_to: "Bildhöhe muss größer oder gleich %{length} Pixel sein"
14
14
  dimension_width_less_than_or_equal_to: "Breite muss kleiner oder gleich %{length} Pixel sein"
15
15
  dimension_height_less_than_or_equal_to: "Höhe muss kleiner oder gleich %{length} Pixel sein"
16
- dimension_width_equal_to: "Breite muss genau %{length} Pixel sein"
17
- dimension_height_equal_to: "Höhe muss genau %{length} Pixel sein"
16
+ dimension_width_equal_to: "Bildbreite muss genau %{length} Pixel sein"
17
+ dimension_height_equal_to: "Bildhöhe muss genau %{length} Pixel sein"
@@ -0,0 +1,22 @@
1
+ es:
2
+ errors:
3
+ messages:
4
+ content_type_invalid: "tiene un tipo de contenido inválido"
5
+ file_size_out_of_range: "tamaño %{file_size} no está entre el rango requerido"
6
+ limit_out_of_range: "el número total está fuera de rango"
7
+ image_metadata_missing: "no es una imagen válida"
8
+ dimension_min_inclusion: "debe ser mayor o igual a %{width} x %{height} pixel"
9
+ dimension_max_inclusion: "debe ser menor o igual a %{width} x %{height} pixel"
10
+ dimension_width_inclusion: "el ancho no se incluye entre %{min} y %{max} pixel"
11
+ dimension_height_inclusion: "la altura no se incluye entre %{min} y %{max} pixel"
12
+ dimension_width_greater_than_or_equal_to: "el ancho debe ser mayor o igual a %{length} pixel"
13
+ dimension_height_greater_than_or_equal_to: "la altura debe ser mayor o igual a %{length} pixel"
14
+ dimension_width_less_than_or_equal_to: "el ancho debe ser menor o igual a %{length} pixel"
15
+ dimension_height_less_than_or_equal_to: "la altura debe ser menor o igual a %{length} pixel"
16
+ dimension_width_equal_to: "el ancho debe ser igual a %{length} pixel"
17
+ dimension_height_equal_to: "la altura debe ser igual a %{length} pixel"
18
+ aspect_ratio_not_square: "debe ser una imagen cuadrada"
19
+ aspect_ratio_not_portrait: "debe ser una imagen de retrato"
20
+ aspect_ratio_not_landscape: "debe ser una imagen de paisaje"
21
+ aspect_ratio_is_not: "debe tener una relación de aspecto de %{aspect_ratio}"
22
+ aspect_ratio_unknown: "tiene una relación de aspecto desconocida"
@@ -0,0 +1,22 @@
1
+ ja:
2
+ errors:
3
+ messages:
4
+ content_type_invalid: "のContent Typeが不正です"
5
+ file_size_out_of_range: "の容量 %{file_size} が許容範囲外です"
6
+ limit_out_of_range: "の数が許容範囲外です"
7
+ image_metadata_missing: "は不正な画像です"
8
+ dimension_min_inclusion: "は %{width} x %{height} ピクセル以上の大きさにしてください"
9
+ dimension_max_inclusion: "は %{width} x %{height} ピクセル以下の大きさにしてください"
10
+ dimension_width_inclusion: "の横幅は %{min} ピクセル以上 %{max} ピクセル以下にしてください"
11
+ dimension_height_inclusion: "の縦幅は %{min} ピクセル以上 %{max} ピクセル以下にしてください"
12
+ dimension_width_greater_than_or_equal_to: "の横幅は %{length} ピクセル以上にしてください"
13
+ dimension_height_greater_than_or_equal_to: "の縦幅は %{length} ピクセル以上にしてください"
14
+ dimension_width_less_than_or_equal_to: "の横幅は %{length} ピクセル以下にしてください"
15
+ dimension_height_less_than_or_equal_to: "の縦幅は %{length} ピクセル以下にしてください"
16
+ dimension_width_equal_to: "の横幅は %{length} ピクセルにしてください"
17
+ dimension_height_equal_to: "の縦幅は %{length} ピクセルにしてください"
18
+ aspect_ratio_not_square: "は正方形にしてください"
19
+ aspect_ratio_not_portrait: "は縦長にしてください"
20
+ aspect_ratio_not_landscape: "は横長にしてください"
21
+ aspect_ratio_is_not: "のアスペクト比は %{aspect_ratio} にしてください"
22
+ aspect_ratio_unknown: "のアスペクト比を取得できませんでした"
@@ -0,0 +1,22 @@
1
+ nl:
2
+ errors:
3
+ messages:
4
+ content_type_invalid: "heeft een ongeldig inhoudstype"
5
+ file_size_out_of_range: "bestandsgrootte %{file_size} valt niet tussen het vereiste bereik"
6
+ limit_out_of_range: "totaal aantal valt buiten het vereiste bereik"
7
+ image_metadata_missing: "is geen geldige afbeelding"
8
+ dimension_min_inclusion: "moet groter of gelijk zijn aan %{width} x %{height} pixels"
9
+ dimension_max_inclusion: "moet kleiner of gelijk zijn aan %{width} x %{height} pixels"
10
+ dimension_width_inclusion: "breedte niet tussen de %{min} en %{max} pixels"
11
+ dimension_height_inclusion: "hoogte niet tussen de %{min} en %{max} pixels"
12
+ dimension_width_greater_than_or_equal_to: "breedte moet groter of gelijk zijn aan %{length} pixels"
13
+ dimension_height_greater_than_or_equal_to: "hoogte moet groter of gelijk zijn aan %{length} pixels"
14
+ dimension_width_less_than_or_equal_to: "breedte moet kleiner of gelijk zijn aan %{length} pixels"
15
+ dimension_height_less_than_or_equal_to: "hoogte moet kleiner of gelijk zijn aan %{length} pixels"
16
+ dimension_width_equal_to: "breedte moet gelijk zijn aan %{length} pixels"
17
+ dimension_height_equal_to: "hoogte moet gelijk zijn aan %{length} pixels"
18
+ aspect_ratio_not_square: "moet een vierkante afbeelding zijn"
19
+ aspect_ratio_not_portrait: "moet een staande afbeelding zijn"
20
+ aspect_ratio_not_landscape: "moet een liggende afbeelding zijn"
21
+ aspect_ratio_is_not: "moet een beeldverhouding hebben van %{aspect_ratio}"
22
+ aspect_ratio_unknown: "heeft een onbekende beeldverhouding"
@@ -0,0 +1,22 @@
1
+ tr:
2
+ errors:
3
+ messages:
4
+ content_type_invalid: "geçersiz dosya tipine sahip"
5
+ file_size_out_of_range: "dosya boyutu %{file_size} gerekli aralık dışında"
6
+ limit_out_of_range: "toplam miktar aralık dışında"
7
+ image_metadata_missing: "geçerli bir imaj değil"
8
+ dimension_min_inclusion: "%{width} x %{height} piksele eşit ya da büyük olmalı"
9
+ dimension_max_inclusion: "%{width} x %{height} piksele eşit ya da küçük olmalı"
10
+ dimension_width_inclusion: "en %{min} ve %{max} piksel aralığı dışında"
11
+ dimension_height_inclusion: "boy %{min} ve %{max} piksel aralığı dışında"
12
+ dimension_width_greater_than_or_equal_to: "en %{length} piksele eşit ya da büyük olmalı"
13
+ dimension_height_greater_than_or_equal_to: "boy %{length} piksele eşit ya da büyük olmalı"
14
+ dimension_width_less_than_or_equal_to: "en %{length} piksele eşit ya da küçük olmalı"
15
+ dimension_height_less_than_or_equal_to: "boy %{length} piksele eşit ya da küçük olmalı"
16
+ dimension_width_equal_to: "en %{length} piksele eşit olmalı"
17
+ dimension_height_equal_to: "boy %{length} piksele eşit olmalı"
18
+ aspect_ratio_not_square: "kare bir imaj olmalı"
19
+ aspect_ratio_not_portrait: "dikey bir imaj olmalı"
20
+ aspect_ratio_not_landscape: "yatay bir imaj olmalı"
21
+ aspect_ratio_is_not: "%{aspect_ratio} en boy oranına sahip olmalı"
22
+ aspect_ratio_unknown: "bilinmeyen en boy oranı"
@@ -1,22 +1,22 @@
1
1
  uk:
2
2
  errors:
3
3
  messages:
4
- content_type_invalid: "має неприпустимий тип вмісту"
5
- file_size_out_of_range: "розмір %{file_size} більше необхідного"
6
- limit_out_of_range: "кількість файлів більше необхідного"
7
- image_metadata_missing: "не є допустимим зображенням"
8
- dimension_min_inclusion: "мусить бути більше або дорівнювати %{width} x %{height} пікселям"
9
- dimension_max_inclusion: "мусить бути менше або дорівнювати %{width} x %{height} пікселям"
10
- dimension_width_inclusion: "ширина не включена між %{min} і %{max} пікселям"
11
- dimension_height_inclusion: "висота не включена між %{min} і %{max} пікселям"
12
- dimension_width_greater_than_or_equal_to: "ширина мусить бути більше або дорівнювати %{length} пікселям"
13
- dimension_height_greater_than_or_equal_to: "висота мусить бути більше або дорівнювати %{length} пікселям"
14
- dimension_width_less_than_or_equal_to: "ширина мусить бути менше або дорівнювати %{length} пікселям"
15
- dimension_height_less_than_or_equal_to: "висота мусить бути менше або дорівнювати %{length} пікселям"
16
- dimension_width_equal_to: "ширина мусить дорівнювати %{length} пікселям"
17
- dimension_height_equal_to: "висота мусить дорівнювати %{length} пікселям"
18
- aspect_ratio_not_square: "мусить бути квадратне зображення"
19
- aspect_ratio_not_portrait: "мусить бути портретне зображення"
20
- aspect_ratio_not_landscape: "мусить бути пейзажне зображення"
21
- aspect_ratio_is_not: "мусить мати співвідношення сторін %{aspect_ratio}"
22
- aspect_ratio_unknown: "має невідоме співвідношення сторін"
4
+ content_type_invalid: "має неприпустимий тип вмісту"
5
+ file_size_out_of_range: "розмір %{file_size} більше необхідного"
6
+ limit_out_of_range: "кількість файлів більше необхідного"
7
+ image_metadata_missing: "не є допустимим зображенням"
8
+ dimension_min_inclusion: "мусить бути більше або дорівнювати %{width} x %{height} пікселям"
9
+ dimension_max_inclusion: "мусить бути менше або дорівнювати %{width} x %{height} пікселям"
10
+ dimension_width_inclusion: "ширина не включена між %{min} і %{max} пікселям"
11
+ dimension_height_inclusion: "висота не включена між %{min} і %{max} пікселям"
12
+ dimension_width_greater_than_or_equal_to: "ширина мусить бути більше або дорівнювати %{length} пікселям"
13
+ dimension_height_greater_than_or_equal_to: "висота мусить бути більше або дорівнювати %{length} пікселям"
14
+ dimension_width_less_than_or_equal_to: "ширина мусить бути менше або дорівнювати %{length} пікселям"
15
+ dimension_height_less_than_or_equal_to: "висота мусить бути менше або дорівнювати %{length} пікселям"
16
+ dimension_width_equal_to: "ширина мусить дорівнювати %{length} пікселям"
17
+ dimension_height_equal_to: "висота мусить дорівнювати %{length} пікселям"
18
+ aspect_ratio_not_square: "мусить бути квадратне зображення"
19
+ aspect_ratio_not_portrait: "мусить бути портретне зображення"
20
+ aspect_ratio_not_landscape: "мусить бути пейзажне зображення"
21
+ aspect_ratio_is_not: "мусить мати співвідношення сторін %{aspect_ratio}"
22
+ aspect_ratio_unknown: "має невідоме співвідношення сторін"
@@ -14,7 +14,7 @@ module ActiveStorageValidations
14
14
  next if is_valid?(file)
15
15
 
16
16
  errors_options[:content_type] = content_type(file)
17
- record.errors.add(attribute, :content_type_invalid, errors_options)
17
+ record.errors.add(attribute, :content_type_invalid, **errors_options)
18
18
  break
19
19
  end
20
20
  end
@@ -52,7 +52,7 @@ module ActiveStorageValidations
52
52
  # Rails 5
53
53
  def validate_each(record, attribute, _value)
54
54
  return true unless record.send(attribute).attached?
55
-
55
+
56
56
  files = Array.wrap(record.send(attribute))
57
57
  files.each do |file|
58
58
  # Analyze file first if not analyzed to get all required metadata.
@@ -110,7 +110,7 @@ module ActiveStorageValidations
110
110
  else
111
111
  if file_metadata[length] != options[length]
112
112
  add_error(record, attribute, options[:message].presence || :"dimension_#{length}_equal_to", length: options[length])
113
- return false
113
+ return false
114
114
  end
115
115
  end
116
116
  end
@@ -119,11 +119,11 @@ module ActiveStorageValidations
119
119
  true # valid file
120
120
  end
121
121
 
122
- def add_error(record, attribute, type, *attrs)
122
+ def add_error(record, attribute, type, **attrs)
123
123
  key = options[:message].presence || type
124
124
  return if record.errors.added?(attribute, key)
125
- record.errors.add(attribute, key, *attrs)
126
- end
125
+ record.errors.add(attribute, key, **attrs)
126
+ end
127
127
 
128
128
  end
129
129
  end
@@ -17,7 +17,7 @@ module ActiveStorageValidations
17
17
  errors_options = { min: options[:min], max: options[:max] }
18
18
 
19
19
  return true if files_count_valid?(files.count)
20
- record.errors.add(attribute, options[:message].presence || :limit_out_of_range, errors_options)
20
+ record.errors.add(attribute, options[:message].presence || :limit_out_of_range, **errors_options)
21
21
  end
22
22
 
23
23
  def files_count_valid?(count)
@@ -16,9 +16,8 @@ module ActiveStorageValidations
16
16
  end
17
17
 
18
18
  def matches?(subject)
19
- @subject = subject.is_a?(Class) ? subject : subject.class
20
-
21
- invalid_when_not_attached && valid_when_attached
19
+ @subject = subject.is_a?(Class) ? subject.new : subject
20
+ responds_to_methods && valid_when_attached && invalid_when_not_attached
22
21
  end
23
22
 
24
23
  def failure_message
@@ -31,17 +30,25 @@ module ActiveStorageValidations
31
30
 
32
31
  private
33
32
 
33
+ def responds_to_methods
34
+ @subject.respond_to?(@attribute_name) &&
35
+ @subject.public_send(@attribute_name).respond_to?(:attach) &&
36
+ @subject.public_send(@attribute_name).respond_to?(:detach)
37
+ end
38
+
34
39
  def valid_when_attached
35
- instance = @subject.new
36
- instance.public_send(@attribute_name).attach(attachable)
37
- instance.validate
38
- instance.errors.details[@attribute_name].exclude?(error: :blank)
40
+ @subject.public_send(@attribute_name).attach(attachable) unless @subject.public_send(@attribute_name).attached?
41
+ @subject.validate
42
+ @subject.errors.details[@attribute_name].exclude?(error: :blank)
39
43
  end
40
44
 
41
45
  def invalid_when_not_attached
42
- instance = @subject.new
43
- instance.validate
44
- instance.errors.details[@attribute_name].include?(error: :blank)
46
+ @subject.public_send(@attribute_name).detach
47
+ # Unset the direct relation since `detach` on an unpersisted record does not set `attached?` to false.
48
+ @subject.public_send("#{@attribute_name}=", nil)
49
+
50
+ @subject.validate
51
+ @subject.errors.details[@attribute_name].include?(error: :blank)
45
52
  end
46
53
 
47
54
  def attachable
@@ -29,7 +29,7 @@ module ActiveStorageValidations
29
29
 
30
30
  def matches?(subject)
31
31
  @subject = subject.is_a?(Class) ? subject.new : subject
32
- allowed_types_allowed? && rejected_types_rejected?
32
+ responds_to_methods && allowed_types_allowed? && rejected_types_rejected?
33
33
  end
34
34
 
35
35
  def failure_message
@@ -46,6 +46,12 @@ module ActiveStorageValidations
46
46
 
47
47
  protected
48
48
 
49
+ def responds_to_methods
50
+ @subject.respond_to?(@attribute_name) &&
51
+ @subject.public_send(@attribute_name).respond_to?(:attach) &&
52
+ @subject.public_send(@attribute_name).respond_to?(:detach)
53
+ end
54
+
49
55
  def allowed_types
50
56
  @allowed_types || []
51
57
  end
@@ -58,7 +58,8 @@ module ActiveStorageValidations
58
58
 
59
59
  def matches?(subject)
60
60
  @subject = subject.is_a?(Class) ? subject.new : subject
61
- width_smaller_than_min? && width_larger_than_min? && width_smaller_than_max? && width_larger_than_max? && width_equals? &&
61
+ responds_to_methods &&
62
+ width_smaller_than_min? && width_larger_than_min? && width_smaller_than_max? && width_larger_than_max? && width_equals? &&
62
63
  height_smaller_than_min? && height_larger_than_min? && height_smaller_than_max? && height_larger_than_max? && height_equals?
63
64
  end
64
65
 
@@ -72,6 +73,12 @@ module ActiveStorageValidations
72
73
 
73
74
  protected
74
75
 
76
+ def responds_to_methods
77
+ @subject.respond_to?(@attribute_name) &&
78
+ @subject.public_send(@attribute_name).respond_to?(:attach) &&
79
+ @subject.public_send(@attribute_name).respond_to?(:detach)
80
+ end
81
+
75
82
  def valid_width
76
83
  ((@width_min || 0) + (@width_max || 2000)) / 2
77
84
  end
@@ -45,7 +45,7 @@ module ActiveStorageValidations
45
45
 
46
46
  def matches?(subject)
47
47
  @subject = subject.is_a?(Class) ? subject.new : subject
48
- lower_than_low? && higher_than_low? && lower_than_high? && higher_than_high?
48
+ responds_to_methods && lower_than_low? && higher_than_low? && lower_than_high? && higher_than_high?
49
49
  end
50
50
 
51
51
  def failure_message
@@ -58,6 +58,12 @@ module ActiveStorageValidations
58
58
 
59
59
  protected
60
60
 
61
+ def responds_to_methods
62
+ @subject.respond_to?(@attribute_name) &&
63
+ @subject.public_send(@attribute_name).respond_to?(:attach) &&
64
+ @subject.public_send(@attribute_name).respond_to?(:detach)
65
+ end
66
+
61
67
  def lower_than_low?
62
68
  @low.nil? || !passes_validation_with_size(@low - 1)
63
69
  end
@@ -19,11 +19,22 @@ module ActiveStorageValidations
19
19
  private
20
20
 
21
21
  def read_image
22
- if file.is_a?(String)
23
- blob = ActiveStorage::Blob.find_signed(file)
22
+ is_string = file.is_a?(String)
23
+ if is_string || file.is_a?(ActiveStorage::Blob)
24
+ if is_string
25
+ # If Rails 5.2 or 6.0, use `find_signed`
26
+ if Rails::VERSION::MAJOR < 6 || (Rails::VERSION::MAJOR == 6 && Rails::VERSION::MINOR == 0)
27
+ blob = ActiveStorage::Blob.find_signed(file)
28
+ # If Rails 6.1 or higher, use `find_signed!`
29
+ elsif Rails::VERSION::MAJOR > 6 || (Rails::VERSION::MAJOR == 6 && Rails::VERSION::MINOR >= 1)
30
+ blob = ActiveStorage::Blob.find_signed!(file)
31
+ end
32
+ else
33
+ blob = file
34
+ end
24
35
 
25
36
  tempfile = Tempfile.new(["ActiveStorage-#{blob.id}-", blob.filename.extension_with_delimiter])
26
- tempfile.binmode
37
+ tempfile.binmode
27
38
 
28
39
  blob.download do |chunk|
29
40
  tempfile.write(chunk)
@@ -25,7 +25,7 @@ module ActiveStorageValidations
25
25
  next if content_size_valid?(file.blob.byte_size)
26
26
 
27
27
  errors_options[:file_size] = number_to_human_size(file.blob.byte_size)
28
- record.errors.add(attribute, :file_size_out_of_range, errors_options)
28
+ record.errors.add(attribute, :file_size_out_of_range, **errors_options)
29
29
  break
30
30
  end
31
31
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveStorageValidations
4
- VERSION = '0.8.7'
4
+ VERSION = '0.9.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_storage_validations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.7
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Kasyanchuk
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-27 00:00:00.000000000 Z
11
+ date: 2021-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -25,35 +25,35 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: 5.2.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: mini_magick
28
+ name: combustion
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 4.9.5
33
+ version: '1.3'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 4.9.5
40
+ version: '1.3'
41
41
  - !ruby/object:Gem::Dependency
42
- name: pry
42
+ name: mini_magick
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 4.9.5
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 4.9.5
55
55
  - !ruby/object:Gem::Dependency
56
- name: rubocop
56
+ name: pry
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: sqlite3
70
+ name: rubocop
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: coffee-rails
84
+ name: sqlite3
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -106,9 +106,13 @@ files:
106
106
  - Rakefile
107
107
  - config/locales/de.yml
108
108
  - config/locales/en.yml
109
+ - config/locales/es.yml
109
110
  - config/locales/fr.yml
111
+ - config/locales/ja.yml
112
+ - config/locales/nl.yml
110
113
  - config/locales/pt-BR.yml
111
114
  - config/locales/ru.yml
115
+ - config/locales/tr.yml
112
116
  - config/locales/uk.yml
113
117
  - lib/active_storage_validations.rb
114
118
  - lib/active_storage_validations/aspect_ratio_validator.rb
@@ -146,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
146
150
  - !ruby/object:Gem::Version
147
151
  version: '0'
148
152
  requirements: []
149
- rubygems_version: 3.0.6
153
+ rubygems_version: 3.0.3
150
154
  signing_key:
151
155
  specification_version: 4
152
156
  summary: Validations for Active Storage