使用model callback最大的缺點就是在測試model時,callback沒辦法關掉。每次做model的save或是destroy時,callback都會被trigger。為了避免callback內的程式被執行,勢必要用stub的方式去處理callback內的程式,這顯然是個糟糕的做法。另一個缺點就是callback有種違反單一責任設計的味道。
ActiveRecord::Observer是將model callback從model切出來放到叫做observer的class中。使用的方式與callback極度類似,官方文件( https://github.com/rails/rails-observers)有詳細的說明,這裡就不再重述。使用上要注意幾點:
ActiveRecord::Observer與callback極度類似,那它的好處在哪裡呢?其實最大的好處就是可以在測試中關掉它。作法是這樣的,在spec/rails_helper.rb中加入下面的設定,將observer先全部關掉。
RSpec.configure do |config|
# ...
config.before(:example) do
# Disable all active record observers by default
ActiveRecord::Base.observers.disable :all
end
# ...
end
等需要測試observer時,再打開它。
require 'rails_helper'
RSpec.describe CourseObserver, type: :model do
describe "after_save" do
it "should do something after save" do
ActiveRecord::Base.observers.enable :course_observer do
# ... the course observer is working here ...
end
end
end
end