Rails Carrierwaveでサムネイルのサイズをモデルごとに変更する
RailsでCarrierwaveで画像のアップロード画面を作っていた。当初は1つのモデルでのみ画像をアップロードしたかったのだが、ユーザーのプロフィール作成画面でも画像アップロード機能を実装したくなった。
そこで思い受かんだ解決方法は4つ。
- 別のアップローダをgenerateしてそれぞれ別のアップローダをマウントする
- 複数のモデルに対応出来るように複数のサイズを作成する
- Carrierwaveのresizeをif式で分岐させて処理を分ける
- 各モデルに任意のサムネイルサイズの定数を定義。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メソッドを変更する等して対応するらしいが今回はその必要がなかったのでここまで。