t__nabe_log

雑多 作業、学習ログ多め。

Rails Carrierwaveでサムネイルのサイズをモデルごとに変更する

RailsでCarrierwaveで画像のアップロード画面を作っていた。当初は1つのモデルでのみ画像をアップロードしたかったのだが、ユーザーのプロフィール作成画面でも画像アップロード機能を実装したくなった。

そこで思い受かんだ解決方法は4つ。

  1. 別のアップローダをgenerateしてそれぞれ別のアップローダをマウントする
  2. 複数のモデルに対応出来るように複数のサイズを作成する
  3. Carrierwaveのresizeをif式で分岐させて処理を分ける
  4. 各モデルに任意のサムネイルサイズの定数を定義。Carrierwaveのアップロードのプロセス中にクラス名と定数を参照させて動的にリサイズする大きさを変更する

このうち1と2はきつい。前者は重複したコードが出来ることになるし後者は無駄な画像が毎回作られることになる。 3か4で迷った。ここは趣味もあると思うけどif式を多用するのに抵抗がある。そこで今回は4を採用してアップローダのコードを変更していった。

モデル

# Userモデル
class User
    THUMBNAIL_SIZE = [100, 100]
    mount_uploader :image, ImageUploader
end

# Photoモデル
class Photo
    THUMBNAIL_SIZE = [700, 700]
    mount_uploader :iamge, ImageUploader
end

アップローダ

マウントするモデルが1つの場合は以下のようにしていた。

# app/uploader/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
    version :thumb do
      process resize_to_fit: [700, 700]
  end
end

複数モデルでthumbのサイズを動的に変更するために以下のように変更

# app/uploader/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base

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

    version :thumb do
      process dynamic_resize_fit
  end
end

これでモデルごとにサムネイルのサイズを変更出来る。 モデルごとにバージョンを用意してサイズやリサイズのメソッド(resize_to_fitやresize_to_limit)を変更したい時はscaleメソッドを変更する等して対応するらしいが今回はその必要がなかったのでここまで。