LoginSignup
3
1

More than 3 years have passed since last update.

ActiveRecord::Baseを継承したクラスに登録されているコールバックを調べる方法

Posted at

例えばTopicというモデルクラスに登録されているコールバックを調べる場合、_*_callbacks*にはvalidationsaveが入る)というメソッドを呼び出すことでコールバックの一覧を取得することができます1。返り値はActiveSupport::Callbacks::CallbackChainのインスタンス。

例)before_saveまたはafter_saveで登録されているコールバックを取得する際の例

_save_callbacksを呼ぶとActiveSupport::Callbacks::CallbackChainのインスタンスが返ります。

Topic._save_callbacks
# => #<ActiveSupport::Callbacks::CallbackChain>

ActiveSupport::Callbacks::CallbackChainEnumerableなので、firstなどで要素を取得するとActiveSupport::Callbacks::Callbackのインスタンスが返ります。

Topic._save_callbacks.first
# => #<ActiveSupport::Callbacks::Callback>

ざっくりコールバック名の一覧を取得したいときは以下のようにします。

# 登録されているコールバック名を取得(※表示している配列は一例です)
Topic._save_callbacks.map{ |c| c.filter }
# => [:store_previous_changes_for_image, :store_image!, :autosave_associated_records_for_site, :write_image_identifier]

beforeコールバックで絞り込みたい場合はkindの値で絞ります。

# beforeで絞り込む
Topic._save_callbacks.select{ |c| c.kind == :before }.map{ |c| c.filter }
# => [:autosave_associated_records_for_site, :write_image_identifier]

afterコールバックについても同様です。

# afterで絞り込む
Topic._save_callbacks.select{ |c| c.kind == :after }.map{ |c| c.filter }
# => [:store_previous_changes_for_image, :store_image!]

とあるafterコールバックが登録されているかどうか?を調べる場合は以下のようにすると良さそうです。

Topic
  ._save_callbacks
  .select{ |c| c.kind == :after }
  .map{ |c| c.filter }
  .include?(:store_image!)

  1. Active Record CallbacksのDebugging callbacksにて詳しい説明がある 

3
1
0

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
3
1