Rails:模型与迁移中的验证

时间:2012-10-29 13:42:02

标签: ruby-on-rails ruby database ruby-on-rails-3 validation

  

可能重复:
  Ruby on Rails: Is it better to validate in the model or the database?

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

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

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

1 个答案:

答案 0 :(得分:25)

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

为什么呢?对于初学者,活动记录不会在所有上下文中强制执行验证。以下方法跳过验证,并将对象保存到数据库,无论其有效性如何:

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

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

所以原因#1 是Rails验证无论如何都不是完全证明:完全依赖它们是有风险的,特别是对于任务关键验证,例如唯一性。

说到这一点,原因#2 (在我的脑海中):activerecord验证容易出现竞争条件,而Rails的唯一性验证器尤其是不能保证唯一性。这里有one article个文件,为什么会这样。

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

原因#3 :为什么在模型和数据库中验证?当然,你复制了一下,但如果Rails错过了像唯一性验证检查这样的东西,那么与支付相比,这通常是一个非常小的问题。这实际上不是一个或两个命题:它总是总是更好地在DB中复制验证,尤其是对于任务关键约束,例如唯一性。

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

参考:Where Correctness Is Enforced(加里伯纳德的截屏视频,需要订阅才能查看)