导轨:验证模型VS迁移

问题描述:

可能重复:
Ruby on Rails: Is it better to validate in the model or the database?导轨:验证模型VS迁移

我看到它有可能在两个轨模型和迁移添加相同的约束/验证。但哪一个是最好的方法?验证模型和数据库级别(以及为什么)是否是一种好的做法?或者他们在轨道上相同?

例如,我们可以对模型和迁移中的名称进行相同的验证

class User < ActiveRecord::Base 
    validates :name, :uniqueness => true, :presence => true 
end 

class CreateUser < ActiveRecord::Migration 
    def change 
    create_table :users do |t| 
     t.string :name, :unique => true, :null => false 
    end 
    end 
end 
+0

好问题。我会说在模型中做它,并让它强制执行到数据库,但我有兴趣听到别人说什么。 – ardochhigh

尽可能在数据库级别以及模型级别进行验证。

为什么?对于初学者来说,主动记录不会在所有情况下强制进行验证。以下方法跳过验证,并且将对象保存到数据库中,无论其有效性:

decrement! 
decrement_counter 
increment! 
increment_counter 
toggle! 
touch 
update_all 
update_attribute 
update_column 
update_counters 

如果传递:validate => falsesave,它也将跳过验证。有关详细信息,请参阅跳过验证的Active Record Validations and Callbacks Guide部分。 (如果你担心,甚至有a gem禁用这些方法。)

所以原因#1是Rails的验证不充分,证明以任何方式:依靠他们完全是有风险的,特别是任务性关键验证,如独特性。

说到这,原因#2(把我的头顶部):ActiveRecord的验证是容易出现竞争情况,和Rails'特别唯一性验证无法保证唯一性。这里有很多文件中的one article这是为什么如此。

尽管它们可能很少发生,但违反唯一性约束可能会损坏整个数据集。在极少数情况下,Rails即将这样做,您不惜一切代价阻止它,这是数据库唯一性约束的来源:数据库的构建是为了处理这种情况,并且会始终如一地执行唯一性,即使Rails没有。

And reason#3:为什么不是验证模型和数据库?当然,你重复了一下,但是与Rails相比,如果Rails没有像唯一性验证检查那样的事情,那通常是一个非常小的问题。这实际上不是一个/或命题:它总是总是更好地复制数据库中的验证,只要你可以,尤其是对于任务关键性约束如独特性。

无论如何,这些都是我的想法,希望有所帮助。

编号:Where Correctness Is Enforced(加里·哈特截屏,需要订阅才能观看)

+1

优秀的答案,远胜于完全重复的问题。 – 18bytes

+7

原因#4:一个数据库本身拥有实体,它可以在Rails应用程序之外使用。 – tokland

+0

@Sundar谢谢!是的,其他答案不是非常有见地...... –