LoginSignup
35
32

More than 5 years have passed since last update.

【日本初?】CarrierWaveでアップロードされた画像の横幅などをValidateする方法

Last updated at Posted at 2013-09-13

弊社ブログ記事からの転載です
CarrierWaveでアップロードされた画像の横幅などをValidateする方法 @ heathrow.lab

最近CarriweWaveのことばかり書いてる気もしますが、気にせず今回もCarrierWaveです。

例えば横幅100px未満の画像がアップロードされた場合、エラーにしたいってことありますよね。
CarrierWaveにデフォルトでそういうValidatorが提供されていればいいんですが、そうでもないのが悩ましい。

では、どういった方法でやればいいのか。
日本語情報がなかったようのなので、弊社で行っている方法を共有してみます。
# Rmagick使います

下準備

1.画像の横幅縦幅を取得するためCarrierWave::RMagickを拡張
2.画像の横幅縦幅を検証するValidatorクラスを作成

まず、CarrierWave::RMagicを拡張します。
このset_dimensionという関数で
アップロードされた画像をRmagickで読み込んで、横幅縦幅を@dimension保存させます。

config/initializers/carrierwave.rb
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で保存した横幅縦幅を検証します。

app/validators/image_size_validator.rb
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を登録してやります。

app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  include CarrierWave::RMagick

  process :set_dimension
end

Modelでこんな風にかけます

app/models/photo.rb
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

35
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
32