Class: Decidim::FileValidatorHumanizer

Inherits:
Object
  • Object
show all
Defined in:
decidim-core/lib/decidim/file_validator_humanizer.rb

Overview

This class fetches the file validation conditions from the active record model objects which have specific validators and uploaders attached to them. This class is used to convert these validation conditions to a human readable format in the front-end and to simplify the code where these are needed from.

This considers if the validation conditions and the uploader have been set directly to the record being validated or if they should be read from another object in case the PassthruValidator is in charge of the validations.

Instance Method Summary collapse

Constructor Details

#initialize(record, attribute) ⇒ FileValidatorHumanizer

Returns a new instance of FileValidatorHumanizer.


15
16
17
18
19
20
21
# File 'decidim-core/lib/decidim/file_validator_humanizer.rb', line 15

def initialize(record, attribute)
  @record = record
  @attribute = attribute
  @passthru_validator ||= record.singleton_class.validators_on(
    attribute
  ).find { |validator| validator.is_a?(PassthruValidator) }
end

Instance Method Details

#extension_allowlistObject

rubocop: enable Metrics/CyclomaticComplexity


76
77
78
79
80
81
82
# File 'decidim-core/lib/decidim/file_validator_humanizer.rb', line 76

def extension_allowlist
  return unless uploader.respond_to?(:extension_allowlist, true)

  # It may be a private method in some uploaders which is why we need to use
  # `#send`.
  uploader.send(:extension_allowlist)
end

#max_file_sizeObject

rubocop: disable Metrics/CyclomaticComplexity


51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'decidim-core/lib/decidim/file_validator_humanizer.rb', line 51

def max_file_size
  # First try if the record itself has a file size validator defined.
  validator = record.singleton_class.validators_on(attribute).find do |v|
    v.is_a?(::ActiveModel::Validations::FileSizeValidator)
  end
  if validator
    lte = validator.options[:less_than_or_equal_to]
    return lte if lte.is_a?(Numeric)
    return lte.call(record) if lte.respond_to?(:call)
  end
  return unless passthru_validator

  # If not, check for the same validator from the pass through record.
  validator = passthru_validator.target_validators(attribute).find do |v|
    v.is_a?(::ActiveModel::Validations::FileSizeValidator)
  end
  return unless validator

  lte = validator.options[:less_than_or_equal_to]
  return lte if lte.is_a?(Numeric)

  lte.call(passthru_record) if lte.respond_to?(:call)
end

#messagesObject


27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'decidim-core/lib/decidim/file_validator_humanizer.rb', line 27

def messages
  messages = []

  if (file_size = max_file_size)
    file_size_mb = (((file_size / 1024 / 1024) * 100) / 100).round
    messages << I18n.t(
      "max_file_size",
      megabytes: file_size_mb,
      scope: "decidim.forms.file_validation"
    )
  end

  if (extensions = extension_allowlist)
    messages << I18n.t(
      "allowed_file_extensions",
      extensions: extensions.join(" "),
      scope: "decidim.forms.file_validation"
    )
  end

  messages
end

#uploaderObject


23
24
25
# File 'decidim-core/lib/decidim/file_validator_humanizer.rb', line 23

def uploader
  @uploader ||= passthru_uploader || record.send(attribute)
end