尽可能在数据库级别和模型级别进行验证。
为什么?对于初学者,活动记录不会在所有上下文中强制验证。以下方法跳过验证,并将对象保存到数据库中而不管其有效性:
decrement!
decrement_counter
increment!
increment_counter
toggle!
touch
update_all
update_attribute
update_column
update_counters
如果你传递:validate => false
给save
,它也会跳过验证。有关详细信息,请参阅跳过验证的Active Record 验证和回调指南部分。(如果这让您担心,甚至还有禁用这些方法的宝石。)
所以原因 #1是 Rails 验证无论如何都不是完全证明的:完全依赖它们是有风险的,特别是对于任务关键型验证,例如唯一性。
说到这一点,原因 #2(我想不通):activerecord 验证容易出现竞争条件,尤其是 Rails 的唯一性验证器不能保证唯一性。这是众多文章中的一篇,它记录了为什么会这样。
尽管它们可能很少发生,但违反唯一性约束可能会破坏整个数据集。在 Rails 即将执行此操作的极少数情况下,您希望不惜一切代价阻止它,这就是 DB 唯一性约束的用武之地:数据库是为处理这种情况而构建的,并且会始终如一地强制执行唯一性,即使 Rails 没有这样做。
原因 #3:为什么不在模型和数据库中都进行验证?当然,你会重复一些,但与 Rails 错过唯一性验证检查之类的东西相比,这通常是一个非常小的问题。这真的不是一个非此即彼的命题:在数据库中尽可能地重复验证总是更好,特别是对于任务关键型约束,例如唯一性。
无论如何,这些是我的想法,希望对您有所帮助。
参考:强制正确性的地方(Gary Bernhardt 的截屏视频,需要订阅才能查看)