在Rails中,除了验证错误之外,我如何找出导致.save()失败的原因?


91

我有一个ActiveRecord模型,该模型true从返回valid?(并且.errors为空),但是false从返回save()。如果模型实例有效,我如何找出导致保存失败的原因?


7
几周前我遇到了这个问题。某些重构使before_save函数始终返回false,这导致保存失败。
杰夫·帕奎特

1
@Jeff-谢谢,事实证明,有一个:before_save方法返回false。你是怎么发现的?只是代码检查吗?
kdt 2011年

这是代码检查,对版本控制进行了比较。
杰夫·帕奎特

Answers:


48

检查所有回调。

我遇到了这样的问题,在我对模型进行了大量更改之后,“ after_validate”方法失败了。该模型有效,但是“ after_validate”返回的是false,因此,如果我使用model.valid它,则说是true,但是如果保存了该模型,则会出现验证错误(从after_validate回调传递过来)。真奇怪

查看应用程序跟踪,您应该能够看到哪些代码行引发了异常。


2
根据Jeff的评论,问题原来是返回false的before_save回调。
kdt 2011年

3
@kdt-正是我的问题所在。我没有考虑过它,因为before_save只是用于设置属性,而是因为将其设置为false值,所以它被隐式返回并且使保存默默地失败。从好的方面来说,我现在可以选择通过添加line来修复此代码"Hey! That's MY fake leg!" # Believe it or not, this is important。不是那样的。;)
内森·朗

2
确保真实返回值的一种好方法是true.tap { do_something }
内森·朗

哇,真是个晦涩的问题。永远都不会猜测返回false的回调将停止保存。有人可以指出我的文档吗?感谢您指出了这一点!
安迪


114

尝试使用爆炸式版本save!(末尾带有感叹号),然后检查产​​生的错误。


4
保存!只是抛出一个RecordNotSaved(当我打印异常的.message时,我只是得到了异常类的名称)。我应该在哪里寻找更多细节?
2011年

1
如果您处于Rails开发模式下,它应该使用堆栈跟踪打印错误的完整描述。在此处查找任何线索,和/或在此处发布。
安迪·林德曼

1
我使用控制台,加载对象(例如o = Object.find #id),然后执行o.save!就像答案说的那样。它打印出为什么不保存。
pduey 2011年

1
仅供参考,调用save!可以引发ActiveRecord::RecordInvalid(因为它运行验证),或者ActiveRecord::RecordNotSaved这就是您想要挽救的对象。
丹尼斯

2
+1,因为这是对如何诊断.save非验证失败的基本问题的最不满意的答案。“最不满意”的资格指的是Rails,而不是这个答案。
Chuck Batson

108

如果@user.save(例如)返回false,则只需运行以下命令即可获取所有错误:

@user.errors.full_messages

12
正如我在问题中提到的,.valid?是正确的-即没有验证错误。我检查了.errors是否也返回了一个空列表(我已经更新了问题以指出这一点)
kdt11 2011年

3

是的,我通过确保在所有before_ *回调中返回true来解决此问题,然后开始工作:)


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.