ActiveModel::Callbacks

ActiveModel::Callbacksを使えばafter_saveなどのコールバックを手軽に実装できる。

まずActiveRecord::Baseのような抽象クラスを次のように定義する。

class AbstractModel
  extend ActiveModel::Callbacks
  define_model_callbacks :save

  def save
    _run_save_callbacks do
      # 具体的なsaveメソッドの内容
      # この前後にbefore_saveとafter_save、そしてaround_saveが呼ばれる
    end
  end
end

重要なのはsaveメソッドの内容をrun_save_callbacksでラップすること。これはコールバックを利用するメソッドに応じて動的に生成され、createメソッドであればrun_create_callbacksを利用する。

そしてコールバックを利用したい具象クラスでは次のようにする。

class SomeModel < AbstractModel
  before_save :foo

  protected

  def foo
    # before_saveで実行したい内容
  end
end

これ以外にもbefore_saveにブロックを渡したり、before_saveをインスタンスメソッドとして定義しているオブジェクトを渡したりすることで処理を実装できる。

define_model_callbacksでは複数のコールバック対象のメソッドを指定することができる。

define_model_callbacks :save, :create

:onlyオプションを使うことで例えばafter_*だけに制限することもできる。

define_model_callbacks :save, :only => :after