【问题标题】:Rails: Validation in model vs migration [duplicate]Rails:模型验证与迁移[重复]
【发布时间】:2012-10-29 13:42:02
【问题描述】:

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

我发现可以在 Rails 模型和迁移中添加相同的约束/验证。但是哪一个是最好的方法?在模型和数据库级别(以及为什么)进行验证是一种好习惯吗?或者他们在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

【问题讨论】:

  • 好问题。我会说在模型中执行它并让它强制执行到数据库中,但我很想听听其他人怎么说。

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


【解决方案1】:

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

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

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

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

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

说到这里,原因 #2(我想不通):activerecord 验证容易出现竞争条件,尤其是 Rails 的唯一性验证器不能保证唯一性。以下是one article,其中许多记录了为什么会这样。

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

原因 #3:为什么在模型和数据库中都进行验证?当然,你会重复一些,但与 Rails 错过唯一性验证检查之类的东西相比,这通常是一个非常小的问题。这真的不是一个非此即彼的命题:总是尽可能地在数据库中重复验证,特别是对于唯一性等关键任务约束。

不管怎样,这些都是我的想法,希望对你有所帮助。

参考:Where Correctness Is Enforced(Gary Bernhardt 截屏,需要订阅才能观看)

【讨论】:

  • 优秀的答案,比完全重复的问题要好得多。
  • 原因 #4:DB 有自己的实体,它可以在 Rails 应用程序之外使用。
  • @Sundar 谢谢!是的,其他答案并不是非常有见地......
  • 不错的答案!但是,您的所有理由都表明最好在数据库级别进行验证。它仍然不能说服我最好在两个级别上进行验证。为什么您还需要在模型级别进行验证?对数据库进行验证还不够吗?
  • @YahyaPoonawala 如果没有 rails 验证器,每次尝试保存无效内容时,您只会在 db 级别收到异常,这显然不理想。举个例子,表单输入的验证错误不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-25
  • 2013-10-24
  • 2013-06-28
  • 1970-01-01
  • 2021-03-21
  • 1970-01-01
相关资源
最近更新 更多