弊社ブログ記事からの転載です
CarrierWaveでアップロードされた画像の横幅などをValidateする方法 @ heathrow.lab
最近CarriweWaveのことばかり書いてる気もしますが、気にせず今回もCarrierWaveです。
例えば横幅100px未満の画像がアップロードされた場合、エラーにしたいってことありますよね。
CarrierWaveにデフォルトでそういうValidatorが提供されていればいいんですが、そうでもないのが悩ましい。
では、どういった方法でやればいいのか。
日本語情報がなかったようのなので、弊社で行っている方法を共有してみます。
# Rmagick使います
下準備
1.画像の横幅縦幅を取得するためCarrierWave::RMagickを拡張
2.画像の横幅縦幅を検証するValidatorクラスを作成
まず、CarrierWave::RMagicを拡張します。
このset_dimensionという関数で
アップロードされた画像をRmagickで読み込んで、横幅縦幅を@dimension保存させます。
module CarrierWave
module RMagick
attr_reader :dimension
def set_dimension
image = Magick::Image.read(current_path).shift
@dimension = { width: image.columns, height: image.rows }
end
end
end
次に、Validatorの作成です。
先ほどの#set_dimensionで保存した横幅縦幅を検証します。
class ImageSizeValidator < ActiveModel::EachValidator
OPTIONS = {
width: {
field: :width,
function: :'==',
message: 'invalid_image_width'
},
max_width: {
field: :width,
function: :'<=',
message: 'invalid_image_max_width'
},
min_width: {
field: :width,
function: :'>=',
message: 'invalid_image_min_width'
},
height: {
field: :height,
function: :'==',
message: 'invalid_image_height'
},
max_height: {
field: :height,
function: :'<=',
message: 'invalid_image_max_height'
},
min_height: {
field: :height,
function: :'>=',
message: 'invalid_image_min_height'
}
}.freeze
def validate_each(object, attribute, value)
return if value.nil? || value.dimension.nil?
dimension = value.dimension
options.each do |key, val|
next unless OPTIONS.key? key
check = OPTIONS[key]
unless dimension[check[:field]].send check[:function], val
object.errors[attribute] << (options[:message] || I18n.t("activerecord.errors.messages.#{check[:message]%[val]}"))
end
end
end
end
使い方
Uploaderに対して#set_dimensionを登録してやります。
class ImageUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
process :set_dimension
end
Modelでこんな風にかけます
class Photo < ActiveRecord::Base
mount_uploader :image1, ImageUploader
mount_uploader :image2, ImageUploader
# 横幅640px、縦幅920pxでなければならない
validates :image1, presence: true, image_size: { width: 640, height: 920 }
# 横幅が100px以上でなければならない
validates :image2, presence: true, image_size: { min_width: 100 }
end
弊社ブログ記事からの転載です
CarrierWaveでアップロードされた画像の横幅などをValidateする方法 @ heathrow.lab