当我需要模型关系时,如何防范错误?

时间:2009-04-29 19:12:02

标签: ruby-on-rails ruby model

我有一个应用程序,它有很多数据库关系,它们相互依赖,可以成功运行应用程序。应用程序中的铰链是一个名为Schedule的模型,但是计划将拉出Blocks,Employee,JobTitle和Assignment(除此之外,每个Block也会从数据库中提取一个赋值)到全天组织员工日程安排。

当我构建应用程序时,我非常重视验证,以确保在将所有内容保存到数据库之前所有部分都必须到位。到目前为止,这已经非常出色,应用程序已经上线了近6个月,每月提供大约150,000个请求,没有打嗝或错误。直到上周。

上周,当某人正在改变计划时,看起来数据库出错,并且计划已保存到数据库,其分配缺失。因为在每个视图中都调用了关联,所以无论何时从数据库调用此调度,应用程序都会在调用nil时抛出NoMethod错误。

以我所声明的方式设计应用程序时,您是否防止数据库/验证可能出现故障?如果是这样,你如何编程防御呢?在将其发送到视图之前,您是否检查了每个关系以确保它不是nil?

我知道这个问题很普遍,如果我的意思更具体,请在评论中告诉我。

4 个答案:

答案 0 :(得分:5)

我建议添加database-enforced foreign key constraintswrapping important groups of operations into transactions

如果某处的Schedule和Assignment之间存在外键,则数据库强制的外键约束将阻止错误插入。此外,如果将特定操作包装在事务中,则可以确保整个插入/更新/删除流发生或失败,恢复到干净状态。

答案 1 :(得分:5)

除了验证和添加其他答案中提到的一些数据库约束之外,您还可能运行后台作业,定期扫描数据库以查找孤立。

当它找到一个时,它会清理它(如果可能的话),或删除它,或者只是将它标记为非活动状态并向您发送电子邮件,以便您以后查看。根据数据的数量和性质,每分钟一次,每小时一次,每天一次......

这样一来,如果不管你有什么保障措施,不良数据就会进入,你很快就会知道它。

答案 2 :(得分:1)

我会在这方面争论非常规的智慧。您描述的约束不属于数据库,它们属于您的OO代码。并且“数据库错误”并不是真的,应用程序插入不正确验证的数据无疑是正确的。

当您开始期望数据库承担这些检查的负担时,您将业务规则放入架构中。至少,这使得编写单元测试变得更加困难(这可能是你应该首先发现的;但现在你有机会再添加一个测试。)

理想情况下,您应该能够将RDBMS替换为其他一些通用数据存储,并且仍然可以在适当的其他位置正确激活所有功能逻辑并保持不变。用户界面不应该与DAL交谈,更不用说直接处理数据库异常了。

如果需要,您可以添加其他数据库约束,但它应该严格地作为备份。正如您所看到的,优雅地处理数据库结构错误(特别是涉及UI时)要困难得多。

答案 3 :(得分:-1)

如果要使应用程序正常运行必须符合要求,那就是assert()的真正含义。我几乎没用过Ruby,但我想它必须有这个概念。使用它们可以在整个代码中的各个位置强制执行前提条件。结合清理和验证外部(用户)输入应该足以保护您。我认为如果在经过大量检查后出现问题,您的应用程序将被允许崩溃(当然是以受控方式)。

我怀疑您遇到的问题是数据库中的错误。更有可能的是,您的验证中存在一些您忽略的边缘情况。