概要
Paperclipを利用した画像アップロードの際に画像の寸法(height, width)をチェックし、
「横幅XXXpx、縦幅YYYpx以下の画像は許可しない」
といった寸法制限を実現します。
環境
- Rails 4.2
- Gem: Paperclip 4.3.0
- ImageMagick 6.9.5-2
実装
image_dimensions_validator.rb
class ImageDimensionsValidator < ActiveModel::EachValidator
CHECKS = { greater_than: :>, greater_than_or_equal_to: :>=,
equal_to: :==, less_than: :<, less_than_or_equal_to: :<= }.freeze
SIDES = [:width, :height].freeze
def validate_each(record, attribute, value)
dimensions = Paperclip::Geometry.from_file(value.queued_for_write[:original].path)
SIDES.each do |side|
next if options[side].blank?
CHECKS.keys.each do |check|
next if options[side][check].blank? || dimensions.send(side).send(CHECKS[check], options[side][check])
record.errors[attribute] << "#{side} (#{dimensions.send(side)}px) must be #{check} #{options[side][check]}px"
end
end
end
def check_validity!
SIDES.each do |side|
next if options[side].blank?
unless CHECKS.keys.any? { |argument| options[side][argument].present? }
fail ArgumentError, "You must pass either :#{CHECKS.keys.join(', :')} to the validator"
end
end
end
end
オプション
- :width
- :height
にそれぞれ、もしくはどちらかにオプションを指定。
オプション.rb
{less_than: INT} # INTより小さい長さの画像ならOK
{less_than_or_equal_to: INT} # INT以下の長さの画像ならOK
{greater_than: INT} # INTより大きい長さの画像ならOK
{greater_than_or_equal_to: INT} # INT以上の長さの画像ならOK
{equal_to: INT} # INTと同じ長さの画像ならOK
使用例
使用例.rb
class SampleImage < ActiveRecord::Base
has_attached_file :file, IMAGE_OPTIONS
# widthが640px以上、かつheightが460px以上の画像ならOK
validates :file, image_dimensions: {
width: {greater_than_or_equal_to: 640},
height: {greater_than_or_equal_to: 460}
}, if: -> {file.dirty?} # upload時のみ寸法のvalidate
....
end
参考
thoughtbot/paperclip
ruby on rails - Paperclip image dimensions custom validator - Stack Overflow:
[ruby] dimensions_validator.rb - CodeGist: