Подтвердить что ты не робот

Список обратных вызовов ActiveRecord

Я уже некоторое время просматриваю источник рельсов, и я не думаю, что есть лучший способ получить список всех обратных вызовов, кроме: ActiveRecord::Callbacks::CALLBACKS - который является постоянным списком.

Значение, если вы используете драгоценный камень, например devise_invitable, который добавляет новый обратный вызов с именем :invitation_accepted со счетом :after и :before, тогда ActiveRecord::Callbacks::CALLBACKS не будет работать.

Знаете ли вы о простом решении, кроме открытия модулей рельсов и убедитесь, что есть внутренний список обратных вызовов в классе модели?

4b9b3361

Ответ 1

Вы можете вызвать Model._save_callbacks, чтобы получить список всех обратных вызовов при сохранении. Затем вы можете отфильтровать его до того, что вам нужно, например. :before или :after следующим образом:

Model._save_callbacks.select {|cb| cb.kind == :before}

Работает одинаково для Model._destroy_callbacks и т.д.

Ответ 2

docs говорят: "Всего было девятнадцать обратных вызовов"... но они, похоже, не говорят, что все эти 19 на самом деле!

Для тех, кто Googled "список всех обратных вызовов ActiveRecord", как я сделал, вот список (найденный с помощью ActiveRecord::Callbacks::CALLBACKS, как описано в вопросе):

:after_initialize
:after_find
:after_touch
:before_validation
:after_validation
:before_save
:around_save
:after_save
:before_create
:around_create
:after_create
:before_update
:around_update
:after_update
:before_destroy
:around_destroy
:after_destroy
:after_commit
:after_rollback

Ответ 3

Обратите внимание, что если вы просто хотите вызвать обратные вызовы, вы можете использовать метод #run_callbacks(kind):

o = Order.find 123 # Created with SQL
o.run_callbacks(:create)
o.run_callbacks(:save)
o.run_callbacks(:commit)

Ответ 4

Если вы работаете в Rails-версии до метода ._save_callbacks, вы можете использовать следующее:

# list of callback_chain methods that return a CallbackChain
Model.methods.select { |m| m.to_s.include? "callback" }.sort

# get all methods in specific call back chain, like after_save
Model.after_save_callback_chain.collect(&:method)

Ответ 5

Я собираюсь предложить наиболее универсальное решение.

Это работает, даже когда драгоценные камни объявляют пользовательские обратные вызовы, например, паранойя и after_real_destroy

Чтобы перечислить все обратные вызовы

Model.methods.select { |m| m.to_s.include? "callback" }.sort

Тогда вы можете получить данные обратные вызовы, если вы наберете имя метода, например

Model._update_callbacks
Model._real_destroy_callbacks
Model._destroy_callbacks

Если вы перечислите все обратные вызовы, то вы можете найти необходимый обратный вызов, проверив переменную экземпляра @filter например:

require 'pp'
Activity._destroy_callbacks.each_with_index { |clbk,index| puts "#{index}-------\n#{clbk.pretty_inspect}" } ; nil 

# [...]

#<ActiveSupport::Callbacks::Callback:0x00007ff14ee7a968
 @chain_config=
  {:scope=>[:kind, :name],
   :terminator=>
    #<Proc:[email protected]/Users/mypc/.rbenv/versions/2.3.7/lib/ruby/gems/2.3.0/gems/activemodel-4.1.16/lib/active_model/callbacks.rb:103 (lambda)>,
   :skip_after_callbacks_if_terminated=>true},
 @filter=
  #<Proc:[email protected]/Users/mypc/.rbenv/versions/2.3.7/lib/ruby/gems/2.3.0/gems/activerecord-4.1.16/lib/active_record/associations/builder/association.rb:135 (lambda)>,
 @if=[],
 @key=70337193825800,
 @kind=:before,
 @name=:destroy,
 @unless=[]>
4-------
#<ActiveSupport::Callbacks::Callback:0x00007ff14ee3a228
 @chain_config=
  {:scope=>[:kind, :name],
   :terminator=>
    #<Proc:[email protected]/Users/mypc/.rbenv/versions/2.3.7/lib/ruby/gems/2.3.0/gems/activemodel-4.1.16/lib/active_model/callbacks.rb:103 (lambda)>,
   :skip_after_callbacks_if_terminated=>true},
 @filter=:audit_destroy,
 @if=[],
 @key=:audit_destroy,
 @kind=:before,
 @name=:destroy,
 @unless=[]>
5-------