20
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

carrierwave で新しいリサイズのバージョンを既存の画像ファイルに適用させる(Rails)

Posted at

やりたいこと

gem の carrierwave で新しいリサイズのバージョンを作る。


新しく retina というバージョンを作る場合、コードだけで言えば、アップローダーの中で

image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  version :retina do
    process :resize_to_fit => [640, 640]
  end
end

と書いて、新しく画像を保存すれば 640 x 640 でリサイズしたものも勝手に保存してくれる。
ただ新しく保存した画像は自動的に 640 x 640 のものが作られるが、
既存の画像は作られず、 @user.image.retina などと書くとエラーが起こる。

@user.image.retina.presence || @user.image

とかにすればもちろん動くが、 retina と使いたい場所全てに書かないとなので、
バージョンが増えてきたら崩壊する。


そこで今回、既存の画像ファイルの retina でリサイズした画像を作っていく。

モデル

User
id
image
user モデルがあり、user はカラムに image を持っている。
app/model/user.rb
class User < ActiveRecord::Base
  mount_uploader :image, ImageUploader
end

image にカラムに ImageUploader の設定を反映させる。

app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  version :retina do
    process :resize_to_fit => [640, 640]
  end
end

こちらの設定は retina のバージョン以外は省略。

リサイズ

リサイズは recreate_versions! というメソッドを使うとできる。
例えば

User.find(1).image.recreate_versions!

で id が 1 のユーザーの画像の retina バージョンが作られる。
もちろん全ユーザーの既存の画像を作り直したいので

User.find_each do { |user| user.image.recreate_versions! if user.image.present? }

とかにするとユーザーの画像が存在した場合にだけ画像を作り直す。
また画像は恐らく量が多いので find_each を使っている。
これをコンソールなどで叩いたらいいのだが、

  • コンソールで打つの面倒臭い
  • 本番環境でコンソールあんまり打ちたくない
    等々あるので、
    どこか適当なファイルに先程のコードを書き(今回は lib/tasks/recreate_image.rb)
rails runner lib/tasks/recreate_image.rb

と叩けば画像のリサイズ完成。


は一応するのだが、
エラーが起きた場合などにしっかり終えるようにしたいのと、
どのくらいまでリサイズが進んでるかとかも見たいので例外処理も加えて

lib/tasks/recreate_versions.rb
User.find_each do |user|
  begin
    p user.id
    usere.image.recreate_versions! if user.image.present?
  rescue
    p "#{user.id} recreate failed."
  end
end

とかすると、多少雑ではあるけど、
id を見て進捗がわかるのと、もしリサイズがうまくいかなかった時はその画像の id を表示してくれるようにしてる。
リサイズできなかったやつは slack などで通知させようとも思ったが、
既存画像のリサイズ自体そんなに頻繁にやるものでもないので今回はやらなかった。


また、そもそも rails runnerコンソール を使わなくても、
どこかのアクションにこの処理を書けばいいのだが、URL を知ってさえすれば誰でも処理を回せてしまうのでコマンド対応にした。

20
20
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
20
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?