執行個體公開方法
define_callbacks(*names) 連結
定義物件生命週期中支援呼叫回事件的集合。
define_callbacks :validate
define_callbacks :initialize, :save, :destroy
選項
-
:terminator
- 決定一個 before 篩選器何時會暫停呼叫回鍊,防止之後的 before 和 around 呼叫回被呼叫,以及事件被觸發。這應該是一個要執行的 lambda。目前物件和呼叫回的結果 lambda 會提供給 terminator lambda。define_callbacks :validate, terminator: ->(target, result_lambda) { result_lambda.call == false }
在此範例中,如果任何 before validate 呼叫回傳回
false
,任何後續的 before 和 around 呼叫回都不會被執行。預設 terminator 會在呼叫回擲回
:abort
時暫停鍊。 -
:skip_after_callbacks_if_terminated
- 決定 after 呼叫回是否應該由:terminator
選項終止。預設上 after 呼叫回會執行,無關於呼叫回鍊是否被終止。如果:terminator
選項設為nil
,這個選項無效。 -
:scope
- 指示物件用於呼叫回時應該執行哪些方法。class Audit def before(caller) puts 'Audit: before is called' end def before_save(caller) puts 'Audit: before_save is called' end end class Account include ActiveSupport::Callbacks define_callbacks :save set_callback :save, :before, Audit.new def save run_callbacks :save do puts 'save in main' end end end
在上述範例中,當你儲存帳號時,方法
Audit#before
會被呼叫。另一方面define_callbacks :save, scope: [:kind, :name]
將會觸發
Audit#before_save
。這是透過呼叫指定執行個體的#{kind}_#{name}
建構的。在此範例中,「kind」為「before」而「name」為「save」。在此脈絡中,:kind
和:name
有特殊含義::kind
指呼叫回種類(before/after/around),而:name
指呼叫回被定義於其上的方法。如下聲明
define_callbacks :save, scope: [:name]
將會呼叫
Audit#save
。
注意事項
傳遞給 define_callbacks
的 names
不能以 !
、?
或 =
結尾。
多次呼叫具有相同 names
的 define_callbacks
會覆寫先前使用 set_callback
註冊的呼叫回。
來源:顯示 | 在 GitHub 上
# File activesupport/lib/active_support/callbacks.rb, line 900 def define_callbacks(*names) options = names.extract_options! names.each do |name| name = name.to_sym ([self] + self.descendants).each do |target| target.set_callbacks name, CallbackChain.new(name, options) end module_eval <<-RUBY, __FILE__, __LINE__ + 1 def _run_#{name}_callbacks(&block) run_callbacks #{name.inspect}, &block end def self._#{name}_callbacks get_callbacks(#{name.inspect}) end def self._#{name}_callbacks=(value) set_callbacks(#{name.inspect}, value) end def _#{name}_callbacks __callbacks[#{name.inspect}] end RUBY end end
reset_callbacks(name) 連結
移除指定事件的所有已設定呼叫回。
來源:顯示 | 在 GitHub 上
# File activesupport/lib/active_support/callbacks.rb, line 810 def reset_callbacks(name) callbacks = get_callbacks name self.descendants.each do |target| chain = target.get_callbacks(name).dup callbacks.each { |c| chain.delete(c) } target.set_callbacks name, chain end set_callbacks(name, callbacks.dup.clear) end
set_callback(name, *filter_list, &block) 連結
安裝指定事件的呼叫回。
set_callback :save, :before, :before_method
set_callback :save, :after, :after_method, if: :condition
set_callback :save, :around, ->(r, block) { stuff; result = block.call; stuff }
第二個參數表示呼叫回應該在事件 :before
、:after
或 :around
時執行。如果省略,則假設為 :before
。這表示上述第一個範例也可以撰寫成
set_callback :save, :before_method
呼叫回可以指定為命名執行個體方法的符號;作為程序、lambda 或區塊;或作為對應到 define_callbacks
的 :scope
參數所決定的特定方法做出回應的物件。
如果給定一個程序、lambda 或區塊,其主體會在目前物件的脈絡中評量。它也可以選擇性地接受目前物件作為參數。
Before 和 around 呼叫回會按設定順序進行呼叫;after 呼叫回會按相反順序進行呼叫。
周圍的回呼函式可以在事件的傳回值,如果事件沒有被停止的話,從 yield
的呼叫存取。
選項
-
:if
- 符號或符號陣列,每個符號命名一個執行個方法或例程;只有在所有符號都傳回 true 值時,才會呼叫回呼函式。如果給定例程,則在目前物件的內容中評估其主體。它也可以選擇將目前物件接受為引數。
-
:unless
- 符號或符號陣列,每個符號命名一個執行個方法或例程;只有在所有符號都傳回 false 值時,才會呼叫回呼函式。如果給定例程,則在目前物件的內容中評估其主體。它也可以選擇將目前物件接受為引數。
-
:prepend
- 如果為true
,會將回呼函式加入到現有的鏈中,而不是附加在後面。
# File activesupport/lib/active_support/callbacks.rb, line 736 def set_callback(name, *filter_list, &block) type, filters, options = normalize_callback_params(filter_list, block) self_chain = get_callbacks name mapped = filters.map do |filter| Callback.build(self_chain, filter, type, options) end __update_callbacks(name) do |target, chain| options[:prepend] ? chain.prepend(*mapped) : chain.append(*mapped) target.set_callbacks name, chain end end
skip_callback(name, *filter_list, &block) Link
略過先前設定的回呼函式。如同 set_callback
,可以傳入 :if
或 :unless
選項,以控制略過回呼函式時機。
注意:此範例使用 PersonRecord
和 #saving_message
;您可以在 此處 看到其定義。
class Writer < PersonRecord
attr_accessor :age
skip_callback :save, :before, :saving_message, if: -> { age > 18 }
end
當 if 選項傳回 true 時,會略過回呼函式。
writer = Writer.new
writer.age = 20
writer.save
輸出
- save
saved
當 if 選項傳回 false 時,不會略過回呼函式。
young_writer = Writer.new
young_writer.age = 17
young_writer.save
輸出
saving...
- save
saved
如果回呼函式尚未設定(除非 :raise
選項設為 false
),將引發 ArgumentError
。
# File activesupport/lib/active_support/callbacks.rb, line 785 def skip_callback(name, *filter_list, &block) type, filters, options = normalize_callback_params(filter_list, block) options[:raise] = true unless options.key?(:raise) __update_callbacks(name) do |target, chain| filters.each do |filter| callback = chain.find { |c| c.matches?(type, filter) } if !callback && options[:raise] raise ArgumentError, "#{type.to_s.capitalize} #{name} callback #{filter.inspect} has not been defined" end if callback && (options.key?(:if) || options.key?(:unless)) new_callback = callback.merge_conditional_options(chain, if_option: options[:if], unless_option: options[:unless]) chain.insert(chain.index(callback), new_callback) end chain.delete(callback) end target.set_callbacks name, chain end end