読者です 読者をやめる 読者になる 読者になる

みかづきメモ

学習したことのメモとか、日記とか、備忘録。

Carrierwave で、 version のサイズを動的に変更する

そんなことより風が強い


Carrierwave っていう、ファイルアップロードに便利な gem があるんだけれども、
その中にある HogeUploader クラスは、アップロード時に画像を加工できます。

class ImageUploader < CarrierWave::Uploader::Base
  # RMagick を使ってやる、 MiniMagick の場合はその下のやつ
  include CarrierWave::RMagick
  # include CarrierWave::MiniMagick

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  process resize_to_fit: [200, 200]

end

こんな感じ。
アップロードした画像が、縦横比を維持して200x200に収まるようしてくれます。

ところで、Carrierwave は便利な機能があって、

version :thumb do
    process risize_to_fit: [100, 100]
end

とかやっておけば、サムネイルみたいなものを作ってくれる。

で、このバージョンのサイズを動的に変えたい場合。
具体的には Model ごとにサイズを変えたかったり。
(User は 64x64 で、 Article は 300x50 みたいな感じ)

モデル

# user.rb
class User
  THUBNAIL_SIZE = [64, 64]
  
  mount_uploader :icon, ImageUploader
  ...
end

# article.rb
class Article
  THUMBNAIL_SIZE = [300, 50]

  mount_uploader :banner, ImageUploader
  ...
end

アップローダ

# image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  ...

  version :thumb, if: :has_thumbnail? do
    process :dynamic_resize_to_fit
  end

  def dynamic_resize_to_fit
    size = model.class::THUMBNAIL_SIZE
    resize_to_fit size[0], size[1]
  end

  def has_thumbnail? new_file
    model.class::const_defined? :THUMBNAIL_SIZE
  end
end

こんな感じでできます。

あとは使いたいところで

.media-left
  = image_tag(user.icon.thumb.url, class: "img-responsive")

とすると、生成されたものが取得できます。