因為Active Model
本身是沒有任何 callback 可用的,因此需要根據您規劃的 lifecycle,額外去自定義。
至於 lifecycle 要怎麼規劃 .. 之後再講。
今天要介紹的是這個方法
define_model_callbacks
舉例,使用 define_model_callbacks :perform
後
就會有 before_perform, around_perform, after_perform
的 callback 可用
使用方式就像 model 的 before_save, after_save 那樣~
另外,define_model_callbacks
可以帶 option :only => symbol or array of symbol
,去限制能用的 callback scope.
For example:
class MyClass
include ActiveModel::Model
define_model_callbacks :initialize, only: :after
# only after 就會只有 after_initialize 可用
after_initialize :cast_values
define_model_callbacks :perform
before_perform :fetch_data
around_perform :handle_error
after_perform :perform_finish
def initialize(params={})
run_callbacks(:initialize) do
puts "把原本的 initialize 包在 run_callbacks(:initialize) 裡面,這樣才會觸發設定好的 callbacks"
super
end
end
def cast_values
puts "在建立物件後,做些實體變數的型別轉換"
end
def perform
run_callbacks(:perform) do
puts "做些這個 service object 應該要做的事情"
end
end
def fetch_data
puts "執行前拉取一些必要資料"
end
def handle_error
puts "注意!如果用到 around callback,一定要開放 block 傳入"
yield
puts "這樣才會順利執行到 run_callbacks(:perform) 裡面的內容"
rescue
puts "around callback 我自己的應用是拿來擷取 error,並印出在畫面上"
end
def perform_finish
puts "執行完成之後做點像是寄送通知之類的事"
end
end
MyClass.new.perform
印出的順序會像下面這樣:
把原本的 initialize 包在 run_callbacks(:initialize) 裡面,這樣才會觸發設定好的 callbacks
在建立物件後,做些實體變數的型別轉換
執行前拉取一些必要資料
注意!如果用到 around callback,一定要開放 block 傳入
做些這個 service object 應該要做的事情
這樣才會順利執行到 run_callbacks(:perform) 裡面的內容
執行完成之後做點像是寄送通知之類的事
但有些同學就會問啦:如果後人想要繼承來擴充或覆寫這個 method ,但我做的 class 已經寫了 run_callbacks
,子層級如果一個不小心覆寫掉導致不會跑 callbacks 怎麼辦?
或者有人會覺得:我的 method 裡面還要加一層 run_callbacks 很不雅觀!
只能說,Ruby 可以玩的 tricky 的奇技淫巧有很多,比如你可以 hack 掉你的 class method new
之類 .. 之後有機會再介紹吧。