active_storage_validations 1.1.3 → 1.1.4

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 (28) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +81 -55
  3. data/lib/active_storage_validations/aspect_ratio_validator.rb +47 -22
  4. data/lib/active_storage_validations/attached_validator.rb +12 -3
  5. data/lib/active_storage_validations/concerns/errorable.rb +38 -0
  6. data/lib/active_storage_validations/concerns/symbolizable.rb +8 -6
  7. data/lib/active_storage_validations/content_type_validator.rb +41 -6
  8. data/lib/active_storage_validations/dimension_validator.rb +15 -15
  9. data/lib/active_storage_validations/limit_validator.rb +44 -7
  10. data/lib/active_storage_validations/matchers/aspect_ratio_validator_matcher.rb +128 -0
  11. data/lib/active_storage_validations/matchers/attached_validator_matcher.rb +20 -23
  12. data/lib/active_storage_validations/matchers/concerns/active_storageable.rb +17 -0
  13. data/lib/active_storage_validations/matchers/concerns/allow_blankable.rb +26 -0
  14. data/lib/active_storage_validations/matchers/concerns/contextable.rb +35 -0
  15. data/lib/active_storage_validations/matchers/concerns/messageable.rb +26 -0
  16. data/lib/active_storage_validations/matchers/concerns/rspecable.rb +25 -0
  17. data/lib/active_storage_validations/matchers/concerns/validatable.rb +5 -10
  18. data/lib/active_storage_validations/matchers/content_type_validator_matcher.rb +39 -25
  19. data/lib/active_storage_validations/matchers/dimension_validator_matcher.rb +61 -44
  20. data/lib/active_storage_validations/matchers/size_validator_matcher.rb +41 -24
  21. data/lib/active_storage_validations/matchers.rb +1 -0
  22. data/lib/active_storage_validations/metadata.rb +42 -28
  23. data/lib/active_storage_validations/processable_image_validator.rb +14 -5
  24. data/lib/active_storage_validations/size_validator.rb +7 -6
  25. data/lib/active_storage_validations/version.rb +1 -1
  26. data/lib/active_storage_validations.rb +1 -1
  27. metadata +9 -3
  28. data/lib/active_storage_validations/error_handler.rb +0 -21
@@ -1,5 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'concerns/active_storageable.rb'
4
+ require_relative 'concerns/allow_blankable.rb'
5
+ require_relative 'concerns/contextable.rb'
6
+ require_relative 'concerns/messageable.rb'
7
+ require_relative 'concerns/rspecable.rb'
3
8
  require_relative 'concerns/validatable.rb'
4
9
 
5
10
  module ActiveStorageValidations
@@ -9,16 +14,35 @@ module ActiveStorageValidations
9
14
  end
10
15
 
11
16
  class DimensionValidatorMatcher
17
+ include ActiveStorageable
18
+ include AllowBlankable
19
+ include Contextable
20
+ include Messageable
21
+ include Rspecable
12
22
  include Validatable
13
23
 
14
24
  def initialize(attribute_name)
25
+ initialize_allow_blankable
26
+ initialize_contextable
27
+ initialize_messageable
28
+ initialize_rspecable
15
29
  @attribute_name = attribute_name
16
30
  @width_min = @width_max = @height_min = @height_max = nil
17
- @custom_message = nil
18
31
  end
19
32
 
20
33
  def description
21
- "validate image dimensions of #{@attribute_name}"
34
+ "validate the image dimensions of :#{@attribute_name}"
35
+ end
36
+
37
+ def failure_message
38
+ message = ["is expected to validate dimensions of :#{@attribute_name}"]
39
+ build_failure_message(message)
40
+ message.join("\n")
41
+ end
42
+
43
+ def width(width)
44
+ @width_min = @width_max = width
45
+ self
22
46
  end
23
47
 
24
48
  def width_min(width)
@@ -31,13 +55,13 @@ module ActiveStorageValidations
31
55
  self
32
56
  end
33
57
 
34
- def with_message(message)
35
- @custom_message = message
58
+ def width_between(range)
59
+ @width_min, @width_max = range.first, range.last
36
60
  self
37
61
  end
38
62
 
39
- def width(width)
40
- @width_min = @width_max = width
63
+ def height(height)
64
+ @height_min = @height_max = height
41
65
  self
42
66
  end
43
67
 
@@ -51,25 +75,18 @@ module ActiveStorageValidations
51
75
  self
52
76
  end
53
77
 
54
- def width_between(range)
55
- @width_min, @width_max = range.first, range.last
56
- self
57
- end
58
-
59
78
  def height_between(range)
60
79
  @height_min, @height_max = range.first, range.last
61
80
  self
62
81
  end
63
82
 
64
- def height(height)
65
- @height_min = @height_max = height
66
- self
67
- end
68
-
69
83
  def matches?(subject)
70
84
  @subject = subject.is_a?(Class) ? subject.new : subject
71
85
 
72
- responds_to_methods &&
86
+ is_a_valid_active_storage_attribute? &&
87
+ is_context_valid? &&
88
+ is_allowing_blank? &&
89
+ is_custom_message_valid? &&
73
90
  width_not_smaller_than_min? &&
74
91
  width_larger_than_min? &&
75
92
  width_smaller_than_max? &&
@@ -79,24 +96,19 @@ module ActiveStorageValidations
79
96
  height_larger_than_min? &&
80
97
  height_smaller_than_max? &&
81
98
  height_not_larger_than_max? &&
82
- height_equals? &&
83
- validate_custom_message?
84
- end
85
-
86
- def failure_message
87
- <<~MESSAGE
88
- is expected to validate dimensions of #{@attribute_name}
89
- width between #{@width_min} and #{@width_max}
90
- height between #{@height_min} and #{@height_max}
91
- MESSAGE
99
+ height_equals?
92
100
  end
93
101
 
94
102
  protected
95
103
 
96
- def responds_to_methods
97
- @subject.respond_to?(@attribute_name) &&
98
- @subject.public_send(@attribute_name).respond_to?(:attach) &&
99
- @subject.public_send(@attribute_name).respond_to?(:detach)
104
+ def build_failure_message(message)
105
+ return unless @failure_message_artefacts.present?
106
+
107
+ message << " but there seem to have issues with the matcher methods you used, since:"
108
+ @failure_message_artefacts.each do |error_case|
109
+ message << " validation failed when provided with a #{error_case[:width]}x#{error_case[:height]}px test image"
110
+ end
111
+ message << " whereas it should have passed"
100
112
  end
101
113
 
102
114
  def valid_width
@@ -108,53 +120,58 @@ module ActiveStorageValidations
108
120
  end
109
121
 
110
122
  def width_not_smaller_than_min?
111
- @width_min.nil? || !passes_validation_with_dimensions(@width_min - 1, valid_height, 'width')
123
+ @width_min.nil? || !passes_validation_with_dimensions(@width_min - 1, valid_height)
112
124
  end
113
125
 
114
126
  def width_larger_than_min?
115
- @width_min.nil? || @width_min == @width_max || passes_validation_with_dimensions(@width_min + 1, valid_height, 'width')
127
+ @width_min.nil? || @width_min == @width_max || passes_validation_with_dimensions(@width_min + 1, valid_height)
116
128
  end
117
129
 
118
130
  def width_smaller_than_max?
119
- @width_max.nil? || @width_min == @width_max || passes_validation_with_dimensions(@width_max - 1, valid_height, 'width')
131
+ @width_max.nil? || @width_min == @width_max || passes_validation_with_dimensions(@width_max - 1, valid_height)
120
132
  end
121
133
 
122
134
  def width_not_larger_than_max?
123
- @width_max.nil? || !passes_validation_with_dimensions(@width_max + 1, valid_height, 'width')
135
+ @width_max.nil? || !passes_validation_with_dimensions(@width_max + 1, valid_height)
124
136
  end
125
137
 
126
138
  def width_equals?
127
- @width_min.nil? || @width_min != @width_max || passes_validation_with_dimensions(@width_min, valid_height, 'width')
139
+ @width_min.nil? || @width_min != @width_max || passes_validation_with_dimensions(@width_min, valid_height)
128
140
  end
129
141
 
130
142
  def height_not_smaller_than_min?
131
- @height_min.nil? || !passes_validation_with_dimensions(valid_width, @height_min - 1, 'height')
143
+ @height_min.nil? || !passes_validation_with_dimensions(valid_width, @height_min - 1)
132
144
  end
133
145
 
134
146
  def height_larger_than_min?
135
- @height_min.nil? || @height_min == @height_max || passes_validation_with_dimensions(valid_width, @height_min + 1, 'height')
147
+ @height_min.nil? || @height_min == @height_max || passes_validation_with_dimensions(valid_width, @height_min + 1)
136
148
  end
137
149
 
138
150
  def height_smaller_than_max?
139
- @height_max.nil? || @height_min == @height_max || passes_validation_with_dimensions(valid_width, @height_max - 1, 'height')
151
+ @height_max.nil? || @height_min == @height_max || passes_validation_with_dimensions(valid_width, @height_max - 1)
140
152
  end
141
153
 
142
154
  def height_not_larger_than_max?
143
- @height_max.nil? || !passes_validation_with_dimensions(valid_width, @height_max + 1, 'height')
155
+ @height_max.nil? || !passes_validation_with_dimensions(valid_width, @height_max + 1)
144
156
  end
145
157
 
146
158
  def height_equals?
147
- @height_min.nil? || @height_min != @height_max || passes_validation_with_dimensions(valid_width, @height_min, 'height')
159
+ @height_min.nil? || @height_min != @height_max || passes_validation_with_dimensions(valid_width, @height_min)
148
160
  end
149
161
 
150
- def passes_validation_with_dimensions(width, height, check)
162
+ def passes_validation_with_dimensions(width, height)
151
163
  mock_dimensions_for(attach_file, width, height) do
152
164
  validate
153
- is_valid?
165
+ is_valid? || add_failure_message_artefact(width, height)
154
166
  end
155
167
  end
156
168
 
157
- def validate_custom_message?
169
+ def add_failure_message_artefact(width, height)
170
+ @failure_message_artefacts << { width: width, height: height }
171
+ false
172
+ end
173
+
174
+ def is_custom_message_valid?
158
175
  return true unless @custom_message
159
176
 
160
177
  mock_dimensions_for(attach_file, -1, -1) do
@@ -3,6 +3,11 @@
3
3
  # Big thank you to the paperclip validation matchers:
4
4
  # https://github.com/thoughtbot/paperclip/blob/v6.1.0/lib/paperclip/matchers/validate_attachment_size_matcher.rb
5
5
 
6
+ require_relative 'concerns/active_storageable.rb'
7
+ require_relative 'concerns/allow_blankable.rb'
8
+ require_relative 'concerns/contextable.rb'
9
+ require_relative 'concerns/messageable.rb'
10
+ require_relative 'concerns/rspecable.rb'
6
11
  require_relative 'concerns/validatable.rb'
7
12
 
8
13
  module ActiveStorageValidations
@@ -12,16 +17,30 @@ module ActiveStorageValidations
12
17
  end
13
18
 
14
19
  class SizeValidatorMatcher
20
+ include ActiveStorageable
21
+ include AllowBlankable
22
+ include Contextable
23
+ include Messageable
24
+ include Rspecable
15
25
  include Validatable
16
26
 
17
27
  def initialize(attribute_name)
28
+ initialize_allow_blankable
29
+ initialize_contextable
30
+ initialize_messageable
31
+ initialize_rspecable
18
32
  @attribute_name = attribute_name
19
33
  @min = @max = nil
20
- @custom_message = nil
21
34
  end
22
35
 
23
36
  def description
24
- "validate file size of #{@attribute_name}"
37
+ "validate file size of :#{@attribute_name}"
38
+ end
39
+
40
+ def failure_message
41
+ message = ["is expected to validate file size of :#{@attribute_name}"]
42
+ build_failure_message(message)
43
+ message.join("\n")
25
44
  end
26
45
 
27
46
  def less_than(size)
@@ -49,36 +68,29 @@ module ActiveStorageValidations
49
68
  self
50
69
  end
51
70
 
52
- def with_message(message)
53
- @custom_message = message
54
- self
55
- end
56
-
57
71
  def matches?(subject)
58
72
  @subject = subject.is_a?(Class) ? subject.new : subject
59
73
 
60
- responds_to_methods &&
74
+ is_a_valid_active_storage_attribute? &&
75
+ is_context_valid? &&
76
+ is_allowing_blank? &&
77
+ is_custom_message_valid? &&
61
78
  not_lower_than_min? &&
62
79
  higher_than_min? &&
63
80
  lower_than_max? &&
64
- not_higher_than_max? &&
65
- validate_custom_message?
66
- end
67
-
68
- def failure_message
69
- "is expected to validate file size of #{@attribute_name} to be between #{@min} and #{@max} bytes"
70
- end
71
-
72
- def failure_message_when_negated
73
- "is expected to not validate file size of #{@attribute_name} to be between #{@min} and #{@max} bytes"
81
+ not_higher_than_max?
74
82
  end
75
83
 
76
84
  protected
77
85
 
78
- def responds_to_methods
79
- @subject.respond_to?(@attribute_name) &&
80
- @subject.public_send(@attribute_name).respond_to?(:attach) &&
81
- @subject.public_send(@attribute_name).respond_to?(:detach)
86
+ def build_failure_message(message)
87
+ return unless @failure_message_artefacts.present?
88
+
89
+ message << " but there seem to have issues with the matcher methods you used, since:"
90
+ @failure_message_artefacts.each do |error_case|
91
+ message << " validation failed when provided with a #{error_case[:size]} bytes test file"
92
+ end
93
+ message << " whereas it should have passed"
82
94
  end
83
95
 
84
96
  def not_lower_than_min?
@@ -101,11 +113,16 @@ module ActiveStorageValidations
101
113
  mock_size_for(io, size) do
102
114
  attach_file
103
115
  validate
104
- is_valid?
116
+ is_valid? || add_failure_message_artefact(size)
105
117
  end
106
118
  end
107
119
 
108
- def validate_custom_message?
120
+ def add_failure_message_artefact(size)
121
+ @failure_message_artefacts << { size: size }
122
+ false
123
+ end
124
+
125
+ def is_custom_message_valid?
109
126
  return true unless @custom_message
110
127
 
111
128
  mock_size_for(io, -1.kilobytes) do
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'active_storage_validations/matchers/aspect_ratio_validator_matcher'
3
4
  require 'active_storage_validations/matchers/attached_validator_matcher'
4
5
  require 'active_storage_validations/matchers/content_type_validator_matcher'
5
6
  require 'active_storage_validations/matchers/dimension_validator_matcher'
@@ -4,29 +4,18 @@ module ActiveStorageValidations
4
4
 
5
5
  attr_reader :file
6
6
 
7
+ DEFAULT_IMAGE_PROCESSOR = :mini_magick.freeze
8
+
7
9
  def initialize(file)
8
10
  require_image_processor
9
11
  @file = file
10
12
  end
11
13
 
12
- def image_processor
13
- Rails.application.config.active_storage.variant_processor
14
- end
15
-
16
- def exception_class
17
- if image_processor == :vips && defined?(Vips)
18
- Vips::Error
19
- elsif defined?(MiniMagick)
20
- MiniMagick::Error
21
- end
22
- end
23
-
24
- def require_image_processor
25
- if image_processor == :vips
26
- require 'vips' unless defined?(Vips)
27
- else
28
- require 'mini_magick' unless defined?(MiniMagick)
29
- end
14
+ def valid?
15
+ read_image
16
+ true
17
+ rescue InvalidImageError
18
+ false
30
19
  end
31
20
 
32
21
  def metadata
@@ -42,14 +31,31 @@ module ActiveStorageValidations
42
31
  {}
43
32
  end
44
33
 
45
- def valid?
46
- read_image
47
- true
48
- rescue InvalidImageError
49
- false
34
+ private
35
+
36
+ def image_processor
37
+ # Rails returns nil for default image processor, because it is set in an after initiliaze callback
38
+ # https://github.com/rails/rails/blob/89d8569abe2564c8187debf32dd3b4e33d6ad983/activestorage/lib/active_storage/engine.rb
39
+ Rails.application.config.active_storage.variant_processor || DEFAULT_IMAGE_PROCESSOR
50
40
  end
51
41
 
52
- private
42
+ def require_image_processor
43
+ case image_processor
44
+ when :vips then require 'vips' unless defined?(Vips)
45
+ when :mini_magick then require 'mini_magick' unless defined?(MiniMagick)
46
+ end
47
+ end
48
+
49
+ def exception_class
50
+ case image_processor
51
+ when :vips then Vips::Error
52
+ when :mini_magick then MiniMagick::Error
53
+ end
54
+ end
55
+
56
+ def vips_image_processor?
57
+ image_processor == :vips
58
+ end
53
59
 
54
60
  def read_image
55
61
  is_string = file.is_a?(String)
@@ -95,8 +101,16 @@ module ActiveStorageValidations
95
101
  end
96
102
 
97
103
  def new_image_from_path(path)
98
- if image_processor == :vips && defined?(Vips) && (Vips::get_suffixes.include?(File.extname(path).downcase) || !Vips::respond_to?(:vips_foreign_get_suffixes))
99
- Vips::Image.new_from_file(path)
104
+ if vips_image_processor? && (Vips::get_suffixes.include?(File.extname(path).downcase) || !Vips::respond_to?(:vips_foreign_get_suffixes))
105
+ begin
106
+ Vips::Image.new_from_file(path)
107
+ rescue exception_class
108
+ # We handle cases where an error is raised when reading the file
109
+ # because Vips can throw errors rather than returning false
110
+ # We stumble upon this issue while reading 0 byte size file
111
+ # https://github.com/janko/image_processing/issues/97
112
+ false
113
+ end
100
114
  elsif defined?(MiniMagick)
101
115
  MiniMagick::Image.new(path)
102
116
  end
@@ -105,13 +119,13 @@ module ActiveStorageValidations
105
119
  def valid_image?(image)
106
120
  return false unless image
107
121
 
108
- image_processor == :vips && image.is_a?(Vips::Image) ? image.avg : image.valid?
122
+ vips_image_processor? && image.is_a?(Vips::Image) ? image.avg : image.valid?
109
123
  rescue exception_class
110
124
  false
111
125
  end
112
126
 
113
127
  def rotated_image?(image)
114
- if image_processor == :vips && image.is_a?(Vips::Image)
128
+ if vips_image_processor? && image.is_a?(Vips::Image)
115
129
  image.get('exif-ifd0-Orientation').include?('Right-top') ||
116
130
  image.get('exif-ifd0-Orientation').include?('Left-bottom')
117
131
  else
@@ -1,27 +1,33 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'concerns/errorable.rb'
3
4
  require_relative 'concerns/symbolizable.rb'
4
5
  require_relative 'metadata.rb'
5
6
 
6
7
  module ActiveStorageValidations
7
8
  class ProcessableImageValidator < ActiveModel::EachValidator # :nodoc
8
9
  include OptionProcUnfolding
9
- include ErrorHandler
10
+ include Errorable
10
11
  include Symbolizable
11
12
 
13
+ ERROR_TYPES = %i[
14
+ image_not_processable
15
+ ].freeze
16
+
12
17
  if Rails.gem_version >= Gem::Version.new('6.0.0')
13
18
  def validate_each(record, attribute, _value)
14
19
  return true unless record.send(attribute).attached?
15
20
 
16
- errors_options = initialize_error_options(options)
17
-
18
21
  changes = record.attachment_changes[attribute.to_s]
19
22
  return true if changes.blank?
20
23
 
21
24
  files = Array.wrap(changes.is_a?(ActiveStorage::Attached::Changes::CreateMany) ? changes.attachables : changes.attachable)
22
25
 
23
26
  files.each do |file|
24
- add_error(record, attribute, :image_not_processable, **errors_options) unless Metadata.new(file).valid?
27
+ if !Metadata.new(file).valid?
28
+ errors_options = initialize_error_options(options, file)
29
+ add_error(record, attribute, ERROR_TYPES.first , **errors_options) unless Metadata.new(file).valid?
30
+ end
25
31
  end
26
32
  end
27
33
  else
@@ -32,7 +38,10 @@ module ActiveStorageValidations
32
38
  files = Array.wrap(record.send(attribute))
33
39
 
34
40
  files.each do |file|
35
- add_error(record, attribute, :image_not_processable, **errors_options) unless Metadata.new(file).valid?
41
+ if !Metadata.new(file).valid?
42
+ errors_options = initialize_error_options(options, file)
43
+ add_error(record, attribute, ERROR_TYPES.first , **errors_options) unless Metadata.new(file).valid?
44
+ end
36
45
  end
37
46
  end
38
47
  end
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'concerns/errorable.rb'
3
4
  require_relative 'concerns/symbolizable.rb'
4
5
 
5
6
  module ActiveStorageValidations
6
7
  class SizeValidator < ActiveModel::EachValidator # :nodoc:
7
8
  include OptionProcUnfolding
8
- include ErrorHandler
9
+ include Errorable
9
10
  include Symbolizable
10
11
 
11
12
  delegate :number_to_human_size, to: ActiveSupport::NumberHelper
@@ -36,14 +37,12 @@ module ActiveStorageValidations
36
37
  return true unless record.send(attribute).attached?
37
38
 
38
39
  files = Array.wrap(record.send(attribute))
39
-
40
- errors_options = initialize_error_options(options)
41
-
42
40
  flat_options = unfold_procs(record, self.options, AVAILABLE_CHECKS)
43
41
 
44
42
  files.each do |file|
45
- next if content_size_valid?(file.blob.byte_size, flat_options)
43
+ next if is_valid?(file.blob.byte_size, flat_options)
46
44
 
45
+ errors_options = initialize_error_options(options, file)
47
46
  errors_options[:file_size] = number_to_human_size(file.blob.byte_size)
48
47
  errors_options[:min_size] = number_to_human_size(min_size(flat_options))
49
48
  errors_options[:max_size] = number_to_human_size(max_size(flat_options))
@@ -55,7 +54,9 @@ module ActiveStorageValidations
55
54
  end
56
55
  end
57
56
 
58
- def content_size_valid?(file_size, flat_options)
57
+ private
58
+
59
+ def is_valid?(file_size, flat_options)
59
60
  return false if file_size < 0
60
61
 
61
62
  if flat_options[:between].present?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveStorageValidations
4
- VERSION = '1.1.3'
4
+ VERSION = '1.1.4'
5
5
  end
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_model'
4
+ require 'active_support/concern'
4
5
 
5
6
  require 'active_storage_validations/railtie'
6
7
  require 'active_storage_validations/engine'
7
8
  require 'active_storage_validations/option_proc_unfolding'
8
- require 'active_storage_validations/error_handler'
9
9
  require 'active_storage_validations/attached_validator'
10
10
  require 'active_storage_validations/content_type_validator'
11
11
  require 'active_storage_validations/size_validator'
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: 1.1.3
4
+ version: 1.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Kasyanchuk
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-21 00:00:00.000000000 Z
11
+ date: 2023-12-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob
@@ -234,14 +234,20 @@ files:
234
234
  - lib/active_storage_validations.rb
235
235
  - lib/active_storage_validations/aspect_ratio_validator.rb
236
236
  - lib/active_storage_validations/attached_validator.rb
237
+ - lib/active_storage_validations/concerns/errorable.rb
237
238
  - lib/active_storage_validations/concerns/symbolizable.rb
238
239
  - lib/active_storage_validations/content_type_validator.rb
239
240
  - lib/active_storage_validations/dimension_validator.rb
240
241
  - lib/active_storage_validations/engine.rb
241
- - lib/active_storage_validations/error_handler.rb
242
242
  - lib/active_storage_validations/limit_validator.rb
243
243
  - lib/active_storage_validations/matchers.rb
244
+ - lib/active_storage_validations/matchers/aspect_ratio_validator_matcher.rb
244
245
  - lib/active_storage_validations/matchers/attached_validator_matcher.rb
246
+ - lib/active_storage_validations/matchers/concerns/active_storageable.rb
247
+ - lib/active_storage_validations/matchers/concerns/allow_blankable.rb
248
+ - lib/active_storage_validations/matchers/concerns/contextable.rb
249
+ - lib/active_storage_validations/matchers/concerns/messageable.rb
250
+ - lib/active_storage_validations/matchers/concerns/rspecable.rb
245
251
  - lib/active_storage_validations/matchers/concerns/validatable.rb
246
252
  - lib/active_storage_validations/matchers/content_type_validator_matcher.rb
247
253
  - lib/active_storage_validations/matchers/dimension_validator_matcher.rb
@@ -1,21 +0,0 @@
1
- module ActiveStorageValidations
2
- module ErrorHandler
3
-
4
- def initialize_error_options(options)
5
- {
6
- validator_type: self.class.to_sym,
7
- custom_message: (options[:message] if options[:message].present?)
8
- }.compact
9
- end
10
-
11
- def add_error(record, attribute, error_type, **errors_options)
12
- type = errors_options[:custom_message].presence || error_type
13
- return if record.errors.added?(attribute, type)
14
-
15
- # You can read https://api.rubyonrails.org/classes/ActiveModel/Errors.html#method-i-add
16
- # to better understand how Rails model errors work
17
- record.errors.add(attribute, type, **errors_options)
18
- end
19
-
20
- end
21
- end