1. Active Recordコールバックとは
コールバックとは、オブジェクトのライフサイクル期間における特定の瞬間に呼び出されるメソッドのことです。コールバックを利用することで、Active Recordオブジェクトが作成/保存/更新/削除/検証/データベースからの読み込み、などのイベント発生時に常に実行されるコードを書くことができます。
2. コールバックの登録方法
- クラスメソッドを利用
class User < ApplicationRecord before_create :generate_username private def generate_username self.username = SecureRandom.hex(6) end end
- ブロックを利用
class User < ApplicationRecord before_create do self.username = SecureRandom.hex(6) end end
3. コールバック一覧
※これらのコールバックは呼び出される順序に並んでいます。
3.1 オブジェクトの作成
コールバック | タイミング |
---|---|
before_validation | バリデーションが行われる直前 |
after_validation | バリデーションの直後 |
before_save | オブジェクトがDBにINSERT、UPDATEされる直前 |
around_save | オブジェクトがDBにINSERT、UPDATEされる最中 |
before_create | オブジェクトがDBにINSERTされる直前 |
around_create | オブジェクトがDBでINSERTされている最中 |
after_create | オブジェクトがDBにINSERTされた直後 |
after_save | オブジェクトをDBにINSERT、UPDATEされた直後 |
3.2 オブジェクトの更新
コールバック | タイミング |
---|---|
before_validation | バリデーションが行われる直前 |
after_validation | バリデーションの直後 |
before_save | オブジェクトがDBにINSERT、UPDATEされる直前 |
around_save | オブジェクトがDBにINSERT、UPDATEされる最中 |
before_update | オブジェクトがDBにUPDATEされる直前 |
around_update | オブジェクトがDBでUPDATEされている最中 |
after_update | オブジェクトがDBにUPDATEされた直後 |
after_save | オブジェクトをDBにINSERT、UPDATEされた直後 |
3.3 オブジェクトの削除
コールバック | タイミング |
---|---|
before_destroy | destroyメソッドで削除される直前 |
around_destroy | オブジェクトがDBでDELETEされている最中 |
after_destroy | destroyメソッドで削除される直前 |
4. コールバックが呼ばれるメソッド
- create
- create!
- destroy
- destroy!
- destroy_all
- save
- save!
- save(validate: false)
- update_attribute
- update
- update!
- valid?
5. コールバックが呼ばれないメソッド
下のメソッドはコールバックが実行されないので、予期しないバグを引き起こす原因になるかもしれないので注意が必要です。
- decrement
- decrement_counter!
- delete
- delete_all
- increment
- increment_counter
- toggle
- touch
- update_column
- update_columns
- update_all
- update_counters
6. 条件つきコールバック
コールバックにif
やunless
オプションを利用し、条件を設定することができます。条件を設定することで指定条件時のみコールバックが実行されます。
- シンボルを利用して条件をつける
class User < ApplicationRecord before_create :generate_username, if: :new_record? private def generate_username self.username = SecureRandom.hex(6) end end
コールバックの条件をシンボルとしてif
またはunless
に渡すことができます。
- Procを利用して条件をつける
class User < ApplicationRecord before_create :generate_username, if: Proc.new { |user| user.new_record? } end
コールバックの条件をProcとして、if
またはunless
に渡すことができます。
7. まとめ
Active Recordのコールバックについてまとめてみました。
頻繁に使うわりに種類が多く、ど忘れしてしまうことがあるので整理することで日々の開発に役立てられればと思います。
今後もActive RecordのAPIの変更に応じて内容を更新していきたいと思います。