2009-12-21 46 views
32

我需要在票据和用户表中创建一行...我只需要知道如何处理事务失败的情况。ActiveRecord事务中的错误处理?

@ticket.transaction do 
    @ticket.save! 
    @user.save! 
end 
    #if (transaction succeeded) 
     #..... 
    #else (transaction failed) 
     #...... 
    #end 

在一个侧面说明我只是想感谢大家谁在堆栈溢出参与帮助设计人员了解更多的编程...我很欣赏你们拿出你一天的时间来回答这样的n00b问题这:)

回答

50

如果您正在使用保存!方法与惊爆(感叹号),应用程序将在保存失败时引发异常。然后你必须捕捉异常来处理失败。

begin 
    @ticket.transaction do 
    @ticket.save! 
    @user.save! 
    end 
    #handle success here 
rescue ActiveRecord::RecordInvalid => invalid 
    #handle failure here 
end 
+0

非常感谢Matt,我很感谢:) – Kevin 2009-12-21 06:54:23

+7

像第一个代码片段(没有抛出异常)的事务根本不是Rails事务。 类似于第二个代码片段的事务应该解救所有异常(rescue => e),处理失败,并且可能再次引发相同的异常。 – Ando 2012-12-08 18:27:27

+7

对不起Ando,但它显然是一个ActiveRecord交易,如“交易”方法所证明。事务的突出之处在于,如果第二个操作失败,则第一个操作(保存故障单)将回滚。这是新开发人员的一个非常基本的例子......显然,人们会用失败处理来替换注释。感谢您分享您关于错误处理的观点,但例子来自Rails的初始作者写的“用Rails进行敏捷Web开发”。所以我会认为你的特征不会抛出异常,因为不是Rails – MattMcKnight 2012-12-08 22:21:51

0

我也是个初学者,但我相信你可以检查@ ticket.errors和@ user.errors和验证,根据他们的反应

还保存方法应该返回确定布尔如果保存成功

1

我使用Rails 2.3.8以下是最好的解决办法:

#Important this have to be nil 
result = nil 

@ticket.transaction do 
    result[true, 'Well done'] 

    result = [false, "Ticket can't be saved"] unless @ticket.save! 
    raise ActiveRecord::Rollback unless result[0] 

    result = [false, "User can't be saved"] unless @user.save! 
    raise ActionRecord::Rollback unless result[0] 
end 

if result[0] 
    flash[:notice] = result[1] 
    #... 
else 
    flash[:warning] = result[1] + "<br> Not so well done" 
end 

确保ü初始化的结果为零,这样您就可以利用之后的事务中所做的更改回滚!