LoginSignup
52

More than 5 years have passed since last update.

ActiveRecordのbefore_saveでうっかり

Posted at

問題

ActiveRecordの before_savebefore_update コールバックに、クライアントコードが直接操作しない属性を設定する処理を書くような機会が結構あると思います。
そこで、次のようなコードを書くわけですが、このコードは意図したどおりに動作しません。理由がすぐにわかるでしょうか?

class Item < ActiveRecord::Base

  before_save :prepare_save # This callback doesn't validate

  def prepare_save
    if hoge_check_ok?
      self.checked = true
    else
      self.checked = false
    end
  end
end

解答

  • prepare_save メソッド内で else を通ったとき、self.checked = false の評価値は false
  • prepare_save メソッドの戻り値が false
  • before_save で指定したコールバックの戻り値が false なので save がキャンセルされて DB に保存されない!

教訓

before_xxx コールバックの最後では selftrue を返そう。

  def prepare_save
    if hoge_check_ok?
      self.checked = true
    else
      self.checked = false
    end
    self
  end

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
52