[保存版] RailsのActive Recordコールバックまとめ

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. 条件つきコールバック

コールバックにifunlessオプションを利用し、条件を設定することができます。条件を設定することで指定条件時のみコールバックが実行されます。

  • シンボルを利用して条件をつける
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の変更に応じて内容を更新していきたいと思います。