文档验证
Overview
在本指南中,您可以学习;了解如何在 Mongoid 模型中定义验证规则。在模型中实现验证后,Mongoid 会阻止您运行违反验证规则的写入操作。 使用文档验证来限制集合中文档字段的数据类型和值范围。
Mongoid 包含 Active Record 中的 ActiveModel::Validations
,用于提供验证功能,包括关联验证器和唯一性验证器。 要学习;了解更多信息,请参阅 Active Record Validations Rails指南和 ActiveModel::Validations Rails API文档。
验证助手
Mongoid 支持 Active Record验证助手,您可以在定义模型类时使用这些助手。 您可以使用这些助手在应用程序中设立通用验证规则,例如检查字段是否存在、将字段值与指定值进行比较或确保字段具有唯一值。
定义验证规则
使用 validates
宏创建验证规则,然后包含验证助手和规则所需的规范。
提示
每个验证助手都接受一个或多个字段名称,这允许您为多个字段定义相同的规则。
以下代码演示了如何使用 presence
验证助手来要求 Person
实例包含 name
字段的值:
class Person include Mongoid::Document field :name, type: String validates :name, presence: true end
常见验证
在本节中,您可以学习;了解以下常见验证规则并查看使用验证助手的示例:
比较规则
您可以使用 comparison
辅助程序根据指定字段的值验证文档。
comparison
助手支持以下选项:
greater_than
:该值必须大于提供的值。greater_than_or_equal_to
:该值必须大于或等于提供的值。equal_to
:该值必须等于提供的值。less_than
:该值必须小于提供的值。less_than_or_equal_to
:该值必须小于或等于提供的值。other_than
:该值必须与提供的值不同。
此示例在 Order
模型上定义了以下比较验证规则:
delivery_date
:必须位于(大于)order_date
的值quantity
:必须小于5
class Order include Mongoid::Document field :order_date, type: DateTime field :delivery_date, type: DateTime field :quantity, type: Integer validates :delivery_date, comparison: { greater_than: :order_date } validates :quantity, comparison: { less_than: 5 } end
格式化规则
您可以使用 format
辅助程序根据字段值是否与正则表达式匹配来验证文档。 使用 with
选项指定正则表达式。
此示例在 User
模型上定义了格式验证规则,以确保 username
字段仅包含字母:
class User include Mongoid::Document field :username, type: String validates :username, format: { with: /\A[a-zA-Z]+\z/ } end
提示
备用助手方法
Mongoid::Document
模块为某些验证提供了宏方法。 您可以使用 validates_format_of
方法,而不是在 validates
宏声明中使用 format
验证助手,如以下代码所示:
validates_format_of :username, with: /\A[a-zA-Z]+\z/
包含或排除规则
您可以使用 inclusion
和 exclusion
辅助程序,根据字段值是否在指定的值列表中来验证文档。 使用 in
选项指定值列表。
此示例在 Order
模型上定义包含验证规则,以确保 shipping
字段值为可接受的值之一:
class Order include Mongoid::Document field :shipping, type: String validates :shipping, inclusion: { in: %w(standard priority overnight) } end
存在或不存在规则
您可以使用 presence
和 absence
辅助程序,根据字段值是存在还是不存在(空)来验证文档。
此示例在 Order
模型上定义了一条缺席验证规则,以确保 delivery_date
字段值为 nil
或空字符串:
class Order include Mongoid::Document field :delivery_date, type: String validates :delivery_date, absence: true end
提示
备用助手方法
Mongoid::Document
模块为某些验证提供了宏方法。 您可以使用 validates_presence_of
方法,而不是在 validates
宏声明中使用 presence
验证助手,如以下代码所示:
validates_presence_of :delivery_date
唯一性规则
您可以使用 uniqueness
辅助程序,根据字段值是否不同于集合中的其他值来验证文档。 您可以使用 scope
选项指定 Mongoid 用于限制唯一性检查的一个或多个字段名称。
此示例在 Person
模型上定义了唯一性验证规则,以确保 first_name
字段值在具有相同 last_name
值的文档中是唯一的:
class Person include Mongoid::Document field :first_name, type: String field :last_name, type: String validates :first_name, uniqueness: { scope: :last_name } end
提示
备用助手方法
Mongoid::Document
模块为某些验证提供了宏方法。 您可以使用 validates_uniqueness_of
方法,而不是在 validates
宏声明中使用 uniqueness
验证助手,如以下代码所示:
validates_uniqueness_of :first_name
当您在模型上使用 validates_uniqueness_of
方法时,Mongoid 会使用 primary
读取偏好(read preference),因为如果它查询从节点(secondary node from replica set)集的从副本集,则可能会读取过时的数据。
此方法采用 conditions
选项,允许您指定在 Mongoid 检查唯一性时添加的条件:
validates_uniqueness_of :name, conditions: -> { where(:age.gte => 10) }
验证关联
您可以使用 validates_associated
辅助程序来验证模型具有的任何关联。 当您包含此验证规则时,Mongoid 会在您每次尝试保存实例时验证任何关联文档。 要学习;了解有关关联的更多信息,请参阅 关联指南。
此示例在 Author
模型上定义了关联验证规则,以便为嵌入式 Book
实例运行验证规则:
class Author include Mongoid::Document embeds_many :books validates_associated :books end
重要
请勿在关联的两端使用 validates_associated
辅助程序,因为这会导致 Mongoid 在无限循环中执行验证。
自定义验证规则
您可以使用 validates_each
和 validates_with
辅助程序来创建自定义验证器。 要学习;了解有关这些助手的更多信息并查看示例,请参阅 Active Record 文档中的 validates_each 和 validates_with 引用。
行为
当您将文档持久保存或保存到数据库时,Mongoid 会执行验证。 以下方法触发验证规则,因此 Mongoid 仅在对象通过验证时才会将对象保存到数据库:
create
save
update
当您使用上述方法的 !
后缀版本时,如果对象验证失败,Mongoid 将返回 Mongoid::Errors::Validations
异常。
触发验证
您可以使用 valid?
方法手动运行验证。 如果对象通过验证,则此方法返回 true
,否则返回 false
:
class Person include Mongoid::Document field :name, type: String field :age, type: Integer validates :age, comparison: { greater_than_or_equal_to: 0 } end # Returns true Person.new(name: "Berta Odom", age: 4).valid? # Returns false Person.new(name: "Cody Peng", age: -5).valid?
对持久性数据运行valid?
时,Mongoid 的行为与 Active Record 不同。 Active Record 的 valid?
会运行所有验证,但 Mongoid 的 valid?
仅对内存中的文档运行验证,以优化性能。
更多信息
要进一步学习;了解可在 Mongoid 模型中使用的字段类型,请参阅 字段类型指南。
要学习;了解有关 Mongoid 中验证方法和宏的更多信息,请参阅API文档中的 Mongoid::Validatable 模块参考。
要查看 Active Record 中验证助手的完整列表,请参阅 Rails API文档中的 ActiveModel::Validations::HelperMethods 参考。