hello-world
webエンジニアのメモ。とりあえずやってみる。

[Rails]carrierwaveのcallbackをskip

公開日時

Railsで画像アップロード機能を作る際に欠かせないgemと言えば carrierwave ですが、save時にcarrierwaveのcallbackをskipしたい場合の対応方法をメモしておきます。

基本的には昨日の Railsで一時的にbefore_saveをskip で書いたskip_callbackとset_callbackを使えばできます。

carrierwaveのドキュメントに「Skipping ActiveRecord callbacks」という項目があり、そこ見ると以下のcallbackがあると分かります。

# avatarのアップロード機能を持つUserモデル
class User
  mount_uploader :avatar, AvatarUploader
end

# アップローダーに追加されるcallback
after_save :store_avatar!
before_save :write_avatar_identifier
after_commit :remove_avatar! :on => :destroy
before_update :store_previous_model_for_avatar
after_save :remove_previously_stored_avatar

上記のUserモデルを例にcarrierwaveのcallbackをskipしたい場合、以下のようにします。

アバターのダミー画像には、 Placehold.jpさんを画像を使用させていただきました。

# carrierwaveのcallbackをskip
User.skip_callback(:save, :after, :store_avatar!)
User.skip_callback(:save, :before, :write_avatar_identifier)
User.skip_callback(:commit, :after, :remove_avatar!)
User.skip_callback(:update, :before, :store_previous_model_for_avatar)
User.skip_callback(:save, :after, :remove_previously_stored_avatar)

# 何かしたい処理を記述
user = User.find(1)
user.remote_avatar_url = 'http://placehold.jp/150x150.png' # avatar画像URL
user.save  # avatarは更新されない

# carrierwaveのcallbackを有効化
User.set_callback(:save, :after, :store_avatar!)
User.set_callback(:save, :before, :write_avatar_identifier)
User.set_callback(:commit, :after, :remove_avatar!)
User.set_callback(:update, :before, :store_previous_model_for_avatar)
User.set_callback(:save, :after, :remove_previously_stored_avatar)

これでcarrierwaveのcallbackを一時的にskipすることができます。

ここ数日、一時的にskipする方法に関する記事ばかりですが、どういうときにこれらを使ったかというのを次の記事でご紹介したいと思います。

参考


Related #carrierwave

[rails]carrierwaveで保存した画像のurlを取得する

carrierwave 0.10.0 で確認 imageカラムにcarrierwaveで保存した画像を保存している場合、デフォルトのままだとだとurlメソッドを実行してもpublic以下のパスのみで http://~ が設定されていません。

[rails]base64エンコードされた画像をcarrierwaveに保存する

Ruby 2.1.4, Rails 4.1.7 で確認 前回はcarrierwaveを使ってPOSTされた画像ファイルの保存を行うAPIを作ってみました。

[rails]carrierwaveを使って画像を保存するAPIサンプル

Ruby 2.1.4, Rails 4.1.7 で確認 画像アップロード機能を作成する際に carrierwaveをよく使うのですが毎回調べているので基本的な設定部分のメモを残しておきます。