コールバックメソッドのカプセル化

複数のテーブルの任意のフィールドにおいて、レコード保存時に同一の処理を行いたかったので、before_saveメソッドをカプセル化するハンドラを作成しました。

  • 共有したいコールバックメソッドを定義したハンドラクラスを、app/models下に作成
class Hoge
  def initialize(attrs_to_manage)
    @attrs_to_manage = attrs_to_manage
  end

  def before_save(model)
    @attrs_to_manage.each do |filed|
      model[field].fugafuga() if model[field]  # 行いたい処理
    end
  end
end

class ActiveRecord::Base
  def self.hogehoge(*attr_names)
    before_save Hoge.new(attr_names)
  end
end
  • 任意のモデルクラスで宣言
class Piyo < ActiveRecord::Base
  require "hoge"
  hogehoge(:attr1, :attr2)
           # 任意のフィールドを渡す
end

ActiveRecord::Baseに直接メソッドを加えるのではなく、ハンドラ内で定義しています。
もし直接加えた場合、モデルではrequireなしにhogehoge()のみ宣言すればよくなるので、アプリケーションの基本ルールとなるような処理の場合にはそちらの方がよいかもしれません。