2015-11-26 62 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中唯一适用于我的变体。