puts
声明必须具有我在这里看不到的某种奇怪的效果......
我有一个Order
型号。模型上有一个回调,其中回调要求模型完全提交;即,我需要使用after_commit
。但是,回调是否应该运行的决定因素需要ActiveRecord::Dirty
因此需要before_save
(或after_save
,但我使用before_save
基于其他一些非必要的信息)。
我把两者结合起来了:
class Order
# not stored in DB, used solely to help the before_save to after_commit transition
attr_accessor :calendar_alert_type, :twilio_alerter
before_save
if self.calendar_alert_type.nil?
if self.new_record?
self.calendar_alert_type = "create, both"
elsif self.email_changed?
self.calendar_alert_type = "update, both"
elsif self.delivery_start_changed? || self.delivery_end_changed? || (type_logistics_attributes_modified.include? "delivery")
self.calendar_alert_type = "update, start"
elsif self.pickup_start_changed? || self.pickup_end_changed? || (type_logistics_attributes_modified.include? "pickup")
self.calendar_alert_type = "update, end"
end
end
puts "whatever"
end
after_commit do
if self.calendar_alert_type.present?
calendar_alert(self.calendar_alert_type)
end
end
end
def calendar_alert(alert_info)
puts "whatever"
alert_type = alert_info.split(",")[0].strip
start_or_end = alert_info.split(",")[1].strip
if start_or_end == "both"
["start","end"].each do |which_end|
Calendar.send(alert_type, which_end, self.id)
end
else
Calendar.send(alert_type, start_or_end, self.id)
end
end
所有私有方法和ActiveRecord::Dirty
语句都正常工作。这是一个规范的例子:
it "email is updated" do
Calendar.should_receive(:send).with("update", "start", @order.id).ordered
Calendar.should_receive(:send).with("update", "end", @order.id).ordered
find("[name='email']").set("nes@example.com")
find(".submit-changes").click
sleep(1)
end
it "phone is updated" do
... #same format as above
end
如果存在puts
个语句,则只有上述所有规范才会传递。我觉得我在这里遗漏了一些非常基本的东西,只是不能把手指放在上面。这是非常奇怪的,因为puts
语句吐出随机文本...
*注意,我完全知道should_receive
应该是expect_to_receive
并且我不应该使用睡眠,并且对功能测试的期望模拟效果不佳。努力将规范与错误的代码日分开更新,但这些不应该导致此问题...(随意纠正我)
答案 0 :(得分:0)
此行为取决于您的Rails版本。在Rails 5之前,您可以返回除false
值之外的任何内容以继续运行。 false
将中止before_*
回调链。 puts 'whatever'
返回零。所以每件事都有效。您的if
阻止似乎返回false
(calendar_alert_type
的自定义实施?)。在这种情况下,链条是固定的。
使用Rails 5,您必须throw(:abort)
才能停止回调处理。