2015-11-26 108 views
4

我已經update定義after_commit回調。它不會在rspec中觸發。``上update` after_commit`回調不會觸發

這裏是我的回調:

after_commit :notify_trip, :if => Proc.new { |trip| trip.can_send_schedule_notification? }, on: :update 

這裏是我的RSpec代碼:

@work_order.update_attributes(:status_id => statuses(:scheduled).id, :tour_id => @tour.id) 
@work_order.run_callbacks(:commit) 
assert_equal 1, ActionMailer::Base.deliveries.size 
expect(ActionMailer::Base.deliveries[0].to).to include(@user.email) 
expect(ActionMailer::Base.deliveries[0].subject).to include("Your trip has been scheduled!") 

這裏回調不調用和返回ActionMailer::Base.deliveries.size0

有任何建議這一點。

+1

我們需要SE codezzz –

+0

如果沒有承諾,也不會觸發。 – sevenseacat

回答

3

根據documentation,您需要使用test_after_commit寶石after_commit鉤子在測試中被解僱。這將不再需要軌道5.0+。

另一種選擇,可以將下面的代碼在其塊體的端部:

subject.run_callbacks(:commit) 
+0

我已經嘗試過它,但它不適用於更新。如果我沒有用'after_commit'提到'update',那麼它就可以很好地工作。 – leena

+0

然後嘗試'subject.run_callbacks(:commit)}'。 – sadaf2605

2

TL; DR

@work_order.update_attributes(:status_id => statuses(:scheduled).id, :tour_id => @tour.id) 
@work_order.instance_variable_set(:@_start_transaction_state, {}) 
@work_order.run_callbacks(:commit) 

說明

我與Rails 4.0.1相同的情況:

@work_order = WorkOrder.create(status_id: 1, order_id: 2) 
@work_order.update_attributes(status_id: 4, order_id: 5) 
@work_order.run_callbacks(:commit) 

當模型實現是這個樣子:

class WorkOrder < ActiveRecord::Base 
    after_commit :notify_trip, :if => Proc.new { |trip| trip.can_send_schedule_notification? }, on: :update 
    after_commit :do_something, on: :create 
end 

,每次當我打電話@work_order.run_callbacks(:commit)那就運行創建方法after_commit - do_something。這是因爲由(@work_order = WorkOrder.create(status_id: 1, order_id: 2))創建@work_order後初始化稱爲@_start_transaction_state一個實例變量,但從來沒有被清除。據我所知,通過閱讀代碼,在ActiveRecord :: Transaction模塊中使用@_start_transaction_state來跟蹤事務處理。

所以調用run_callbacks之前,如果我們清理@_start_transaction_state,那麼我們就能夠運行after_commit on: update回調

@work_order.instance_variable_set(:@_start_transaction_state, {}) 
@work_order.run_callbacks(:commit) 

還有一個選擇是一點點清潔:

@work_order.send(:clear_transaction_record_state) 
@work_order.run_callbacks(:commit) 

我知道這個解決方案很冒險,我不確定這是否會引入一些副作用,特別是在嵌套事務中,但是在Rails 4.0.1中唯一適用於我的變體。