class ActiveStorageValidations::AspectRatioValidator

Constants

AVAILABLE_CHECKS
PRECISION

Public Class Methods

new(options) click to toggle source
Calls superclass method
# File lib/active_storage_validations/aspect_ratio_validator.rb, line 10
def initialize(options)
  require 'mini_magick' unless defined?(MiniMagick)
  super(options)
end

Public Instance Methods

check_validity!() click to toggle source
# File lib/active_storage_validations/aspect_ratio_validator.rb, line 16
def check_validity!
  return true if AVAILABLE_CHECKS.any? { |argument| options.key?(argument) }
  raise ArgumentError, 'You must pass "aspect_ratio: :OPTION" option to the validator'
end
validate_each(record, attribute, _value) click to toggle source
# File lib/active_storage_validations/aspect_ratio_validator.rb, line 22
def validate_each(record, attribute, _value)
  return true unless record.send(attribute).attached?

  changes = record.attachment_changes[attribute.to_s]
  return true if changes.blank?

  files = Array.wrap(changes.is_a?(ActiveStorage::Attached::Changes::CreateMany) ? changes.attachables : changes.attachable)

  files.each do |file|
    metadata = Metadata.new(file).metadata
    next if is_valid?(record, attribute, metadata)
    break
  end
end

Private Instance Methods

add_error(record, attribute, type, interpolate = options[:with]) click to toggle source
# File lib/active_storage_validations/aspect_ratio_validator.rb, line 93
def add_error(record, attribute, type, interpolate = options[:with])
  key = options[:message].presence || type
  return if record.errors.added?(attribute, key)
  record.errors.add(attribute, key, aspect_ratio: interpolate)
end
is_valid?(record, attribute, metadata) click to toggle source
# File lib/active_storage_validations/aspect_ratio_validator.rb, line 58
def is_valid?(record, attribute, metadata)
  if metadata[:width].to_i <= 0 || metadata[:height].to_i <= 0
    add_error(record, attribute, options[:message].presence || :image_metadata_missing)
    return false
  end

  case options[:with]
  when :square
    return true if metadata[:width] == metadata[:height]
    add_error(record, attribute, :aspect_ratio_not_square)

  when :portrait
    return true if metadata[:height] > metadata[:width]
    add_error(record, attribute, :aspect_ratio_not_portrait)

  when :landscape
    return true if metadata[:width] > metadata[:height]
    add_error(record, attribute, :aspect_ratio_not_landscape)

  else
    if options[:with] =~ /is\_(\d*)\_(\d*)/
      x = $1.to_i
      y = $2.to_i

      return true if (x.to_f / y).round(PRECISION) == (metadata[:width].to_f / metadata[:height]).round(PRECISION)

      add_error(record, attribute, :aspect_ratio_is_not, "#{x}x#{y}")
    else
      add_error(record, attribute, :aspect_ratio_unknown)
    end
  end
  false
end