简体   繁体   English

Ruby on Rails:在模型或数据库中验证是否更好?

[英]Ruby on Rails: Is it better to validate in the model or the database?

Is it generally better practice (and why) to validate attributes in the model or in the database definition? 通常更好的做法(以及为什么)验证模型或数据库定义中的属性?

For (a trivial) example: 对于(一个微不足道的)例子:

In the user model: 在用户模型中:

validates_presence_of :name

versus in the migration: 与迁移相比:

t.string :name, :null => false 

On the one hand, including it in the database seems more of a guarantee against any type of bad data sneaking in. On the other hand, including it in the model makes things more transparent and easier to understand by grouping it in the code with the rest of the validations. 一方面,将其包含在数据库中似乎更能​​保证不会出现任何类型的坏数据。另一方面,将其包含在模型中会使事情更加透明,更容易理解,方法是将其分组到代码中。其余的验证。 I also considered doing both, but this seems both un-DRY and less maintainable. 我也考虑过两者兼顾,但这似乎既不干,也不易维护。

I would highly recommend doing it in both places. 我强烈建议在两个地方都这样做。 Doing it in the model saves you a database query (possibly across the network) that will essentially error out, and doing it in the database guarantees data consistency. 在模型中执行此操作可以为您节省数据库查询(可能在整个网络中),这些查询本质上会出错,并且在数据库中执行此操作可确保数据一致性。

And also 并且

validates_presence_of :name

not the same to 不一样的

t.string :name, :null => false 

If you just set NOT NULL column in your DB you still can insert blank value (""). 如果只在数据库中设置NOT NULL列,则仍可以插入空值(“”)。 If you're using model validates_presence_of - you can't. 如果您使用的是模型validates_presence_of - 则不能。

It is good practice to do both. 两者都是好的做法。 Model Validation is user friendly while database validation adds a last resort component which hardens your code and reveals missing validitions in your application logic. 模型验证是用户友好的,而数据库验证添加了最后的组件,可以加强代码并显示应用程序逻辑中缺少的验证。

It varies. 它有所不同。 I think that simple, data-related validation (such as string lengths, field constraints, etc...) should be done in the database. 我认为应该在数据库中完成简单的,与数据相关的验证(例如字符串长度,字段约束等)。 Any validation that is following some business rules should be done in the model. 遵循某些业务规则的任何验证都应在模型中完成。

I would recommend Migration Validators project ( https://rubygems.org/gems/mv-core ) to define validation on db level and then transparently promote it to ActiveRecord model. 我建议使用Migration Validators项目( https://rubygems.org/gems/mv-core )来定义db级别的验证,然后将其透明地提升为ActiveRecord模型。

Example: 例:

in migration: 在迁移中:

def change
  create_table :posts do |t|
    t.string :title, length: 1..30
  end 
end

in your model: 在你的模型中:

class Post < ActiveRecord::Base
  enforce_migration_validations
end

As result you will have two level data validation. 因此,您将获得两级数据验证。 The first one will be implemented in db ( as condition in trigger of check constraint ) and the second one as ActiveModel validation in your model. 第一个将在db中实现(作为检查约束的触发条件),第二个将在模型中作为ActiveModel验证。

取决于您的应用程序设计,如果您有一个中小型应用程序,您可以在两者中或仅在模型中执行它,但如果您有一个大型应用程序可能是面向服务或层次,那么具有基本验证,即强制/可空,数据库中的最小/最大长度等,更严格,即模型中的模式或业务规则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM