【独家】关于Validation的方法使用
来源:博客园      时间:2023-04-20 22:27:09
acceptance验证

acceptance是 Rails 中的一个验证器(validator),用于验证一个布尔类型的属性是否被接受。在表单中,通常会有一些复选框或单选按钮,用户需要勾选或选择才能提交表单。acceptance验证器用于确保这些复选框或单选按钮已经被选中或勾选。

当一个属性被验证时,acceptance验证器会检查该属性是否为 true。如果为 true,则验证通过;否则,验证失败,并将错误信息添加到模型对象的 errors集合中。


(资料图片)

例如,在下面的代码中,acceptance验证器用于验证 terms_of_service属性是否被接受:

class Person < ApplicationRecord  validates :terms_of_service, acceptance: trueend

在这个例子中,如果一个 Person对象的 terms_of_service属性没有被设置为 true,那么该对象就无法通过验证,并且会在 errors集合中添加一个名为 terms_of_service的错误信息。

在表单中,可以使用 Rails 提供的 check_boxradio_button辅助方法来生成复选框或单选按钮,并自动添加 acceptance验证器。例如:

<%= form_for @person do |f| %>  <%= f.label :terms_of_service do %>    <%= f.check_box :terms_of_service %>    I agree to the terms of service  <% end %><% end %>

这个表单会生成一个名为 terms_of_service的复选框,并自动将其关联到 Person模型类的 terms_of_service属性。当用户提交表单时,如果复选框被选中,那么该属性会被设置为 true,并且表单数据就可以被提交。如果复选框没有被选中,那么表单数据无法通过验证,并且会显示一个名为 terms_of_service的错误信息。

validates_associated

当您的模型与其他模型有关联,并且它们也需要验证时,您应该使用这个帮助器。当你试图保存对象时,有效吗?将在每个相关对象上调用。

class Library < ApplicationRecord  has_many :books  validates_associated :booksend

这段代码是一个 Rails 应用程序中的 ActiveRecord 模型类,它用于定义一个名为 Library的类,并建立了与 Book模型类的关联关系。它使用了 has_many方法来指定一个图书馆可以拥有多本书,并使用了 validates_associated方法来确保与该模型关联的书籍数据也是有效的。

has_many方法用于在模型类之间建立一对多的关联关系。在这个例子中,Library模型类通过 has_many :books方法指定一个图书馆可以拥有多本书。这个方法会自动为 Library类生成一个名为 books的实例方法,该方法用于返回与该图书馆相关联的所有书籍的集合。同时,它还会自动为 Book类生成一个名为 library的实例方法,该方法用于返回与该书籍相关联的图书馆对象。

validates_associated方法用于验证与该模型类关联的其他模型类的数据是否有效。在这个例子中,validates_associated :books方法用于验证与 Library模型类关联的所有书籍数据是否有效。如果任何一本书籍的数据无效,那么整个图书馆对象都无法通过验证,并且会在模型对象的 errors集合中添加一个名为 books的错误信息。

需要注意的是,validates_associated方法只验证与该模型类关联的其他模型类的数据是否有效,而不会验证该模型类本身的数据是否有效。因此,如果需要同时验证该模型类本身的数据和与其关联的其他模型类的数据,还需要使用其他的验证器来实现。

confirmation确认
class Person < ApplicationRecord  validates :email, confirmation: trueend

这段代码是一个 Rails 应用程序中的 ActiveRecord 模型类,它用于定义一个名为 Person的类,并对其中的 email属性进行验证。

在这个例子中,validates方法用于为 email属性添加验证规则。具体来说,使用了 confirmation选项,表示需要对 email属性进行确认验证。这意味着在表单中提交时,除了输入 email属性的值之外,还需要再次输入相同的值,以便验证两次输入的值是否一致。如果两次输入的值不一致,则会在模型对象的 errors集合中添加一个名为 email_confirmation的错误信息。

需要注意的是,confirmation验证器只适用于需要确认的属性,例如密码和电子邮件地址等。如果要对其他类型的属性进行验证,可以使用其他的验证器来实现。

class Person < ApplicationRecord  validates :email, confirmation: true  validates :email_confirmation, presence: trueend

这段代码是一个 Rails 应用程序中的 ActiveRecord 模型类,它用于定义一个名为 Person的类,并对其中的 email属性进行验证。

在这个例子中,validates方法用于为 email属性添加验证规则。具体来说,使用了 confirmation选项,表示需要对 email属性进行确认验证。这意味着在表单中提交时,除了输入 email属性的值之外,还需要再次输入相同的值,以便验证两次输入的值是否一致。如果两次输入的值不一致,则会在模型对象的 errors集合中添加一个名为 email_confirmation的错误信息。

在这个例子中,还添加了另一个验证规则,用于验证 email_confirmation属性的存在性。这是因为在进行 email属性的确认验证时,需要通过表单中的 email_confirmation属性来获取确认电子邮件地址的值。因此,如果 email_confirmation属性不存在或为空,确认验证将无法进行,因此需要验证其存在性。

需要注意的是,confirmation验证器只适用于需要确认的属性,例如密码和电子邮件地址等。如果要对其他类型的属性进行验证,可以使用其他的验证器来实现。

验证大小写

class Person < ApplicationRecord  validates :email, confirmation: { case_sensitive: false }end

这段代码是一个 Rails 应用程序中的 ActiveRecord 模型类,它用于定义一个名为 Person的类,并对其中的 email属性进行验证。

在这个例子中,validates方法用于为 email属性添加验证规则。具体来说,使用了 confirmation选项,并传递了一个名为 case_sensitive的哈希参数,将其设置为 false。这意味着在进行电子邮件地址确认验证时,将忽略电子邮件地址的大小写。例如,如果 email属性的值为 "example@example.com",则确认验证器会接受 "Example@example.com" 或其他任何大小写组合的电子邮件地址作为有效值。

需要注意的是,confirmation验证器只适用于需要确认的属性,例如密码和电子邮件地址等。如果要对其他类型的属性进行验证,可以使用其他的验证器来实现。

comparison比较
class Promotion < ApplicationRecord  validates :start_date, comparison: { greater_than: :end_date }end

这段代码是一个 Rails 应用程序中的 ActiveRecord 模型类,它用于定义一个名为 Promotion的类,并对其中的 start_date属性进行验证。

在这个例子中,validates方法用于为 start_date属性添加验证规则。具体来说,使用了 comparison选项,并传递了一个名为 greater_than的哈希参数,将其设置为 end_date。这意味着要验证 start_date属性的值是否大于 end_date属性的值。

需要注意的是,comparison验证器是 Rails 6 中引入的新特性,在 Rails 5 中不存在。它用于比较两个属性的值,并验证它们之间的关系,包括大于、小于、大于等于、小于等于等关系。在本例中,使用了 greater_than选项,表示要验证 start_date属性的值是否大于 end_date属性的值。

在实际使用中,可以在表单中添加名为 start_dateend_date的日期选择器,用于输入促销活动的开始日期和结束日期。例如:

<%= form_for @promotion do |f| %>  <%= f.label :start_date %>  <%= f.date_field :start_date %>  <%= f.label :end_date %>  <%= f.date_field :end_date %>  <%= f.submit "Save" %><% end %>

这个表单会生成名为 start_dateend_date的日期选择器,用于输入促销活动的开始日期和结束日期。当用户提交表单时,它会验证 start_date属性的值是否大于 end_date属性的值,并将模型对象存储到数据库中。如果 start_date属性的值小于或等于 end_date属性的值,则会显示一个名为 start_date的错误信息。

这些是 Active Record 验证器 comparison选项中可用的比较运算符及其默认错误消息:

:greater_than- 指定值必须大于提供的值。该选项的默认错误消息为 "必须大于 %{count}"。:greater_than_or_equal_to- 指定值必须大于或等于提供的值。该选项的默认错误消息为 "必须大于或等于 %{count}"。:equal_to- 指定值必须等于提供的值。该选项的默认错误消息为 "必须等于 %{count}"。:less_than- 指定值必须小于提供的值。该选项的默认错误消息为 "必须小于 %{count}"。:less_than_or_equal_to- 指定值必须小于或等于提供的值。该选项的默认错误消息为 "必须小于或等于 %{count}"。:other_than- 指定值必须不等于提供的值。该选项的默认错误消息为 "必须不等于 %{count}"。

这些选项可以用于在 Active Record 模型中验证属性的值是否符合指定的比较运算符。例如,可以使用 :greater_than选项来验证某个属性的值必须大于指定的值:

validates :some_attribute, comparison: { greater_than: 10 }

这会在模型对象上添加一个验证规则,以确保 some_attribute属性的值大于 10。如果该属性的值小于或等于 10,则会在模型对象的 errors集合中添加一个错误消息,该消息的内容为 "must be greater than 10"。如果需要自定义错误消息,可以在 validates方法中使用 message选项来指定它,例如:

validates :some_attribute, comparison: { greater_than: 10, message: "must be greater than 10!" }

这会在模型对象上添加一个验证规则,以确保 some_attribute属性的值大于 10。如果该属性的值小于或等于 10,则会在模型对象的 errors集合中添加一个错误消息,该消息的内容为 "must be greater than 10!"。

exclusion排除
class Account < ApplicationRecord  validates :subdomain, exclusion: { in: %w(www us ca jp),    message: "%{value} is reserved." }end

这段代码是一个 Rails 应用程序中的 ActiveRecord 模型类,它用于定义一个名为 Account的类,并对其中的 subdomain属性进行验证。

在这个例子中,validates方法用于为 subdomain属性添加验证规则。具体来说,使用了 exclusion选项,并传递了一个哈希参数,将其设置为 in选项为 ["www", "us", "ca", "jp"]。这意味着要验证 subdomain属性的值是否不在这个数组中。

如果 subdomain属性的值在指定的数组中,将会在模型对象的 errors集合中添加一个错误消息,该消息的内容为 "%{value} is reserved.",其中 %{value}会被替换为实际的属性值。

在实际使用中,这个验证器可以用于确保用户输入的 subdomain属性值不是某些预留的关键字,例如在一个多租户的应用程序中,可能需要保留一些子域名用于系统的内部使用,而不允许用户创建这些子域名。例如:

validates :subdomain, exclusion: { in: %w(www us ca jp),  message: "%{value} is reserved for internal use." }

这个验证器会在用户提交表单时验证 subdomain属性,并确保其值不在 ["www", "us", "ca", "jp"]数组中。如果 subdomain属性的值在指定的数组中,将会显示一个错误消息,该消息的内容为 "%{value} is reserved for internal use."。如果需要自定义错误消息,可以在 validates方法中使用 message选项来指定它。

format格式
class Product < ApplicationRecord  validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/,    message: "only allows letters" }end

这段代码是一个 Rails 应用程序中的 ActiveRecord 模型类,它用于定义一个名为 Product的类,并对其中的 legacy_code属性进行验证。

在这个例子中,validates方法用于为 legacy_code属性添加验证规则。具体来说,使用了 format选项,并传递了一个哈希参数,将其设置为 with选项为 /\A[a-zA-Z]+\z/。这意味着要验证 legacy_code属性的值是否只包含字母,且不包含空格、数字或其他字符。

如果 legacy_code属性的值不符合指定的正则表达式,则会在模型对象的 errors集合中添加一个错误消息,该消息的内容为 "only allows letters"。

在实际使用中,这个验证器可以用于确保用户输入的 legacy_code属性值只包含字母,例如在一个产品管理系统中,可能需要保证产品的代码是由字母组成的,而不允许包含其他字符。例如:

validates :legacy_code, format: { with: /\A[a-zA-Z]+\z/,  message: "only allows letters and no other characters or spaces" }

这个验证器会在用户提交表单时验证 legacy_code属性,并确保其值只包含字母。如果 legacy_code属性的值包含非字母字符,则会显示一个错误消息,该消息的内容为 "only allows letters and no other characters or spaces"。如果需要自定义错误消息,可以在 validates方法中使用 message选项来指定它。

inclusion包含
class Coffee < ApplicationRecord  validates :size, inclusion: { in: %w(small medium large),    message: "%{value} is not a valid size" }end

这段代码是一个 Rails 应用程序中的 ActiveRecord 模型类,它用于定义一个名为 Coffee的类,并对其中的 size属性进行验证。

在这个例子中,validates方法用于为 size属性添加验证规则。具体来说,使用了 inclusion选项,并传递了一个哈希参数,将其设置为 in选项为 ["small", "medium", "large"]。这意味着要验证 size属性的值是否在指定的数组中。

如果 size属性的值不在指定的数组中,则会在模型对象的 errors集合中添加一个错误消息,该消息的内容为 "%{value} is not a valid size",其中 %{value}会被替换为实际的属性值。

在实际使用中,这个验证器可以用于确保用户输入的 size属性值是预定义的值之一,例如在一个咖啡店管理系统中,可能需要确保咖啡杯的大小是预定义的几种规格之一,而不允许用户输入其他值。例如:

validates :size, inclusion: { in: %w(small medium large),  message: "%{value} is not a valid cup size. Please choose small, medium or large." }

这个验证器会在用户提交表单时验证 size属性,并确保其值是 ["small", "medium", "large"]数组中的一项。如果 size属性的值不在指定的数组中,则会显示一个错误消息,该消息的内容为 "%{value} is not a valid cup size. Please choose small, medium or large."。如果需要自定义错误消息,可以在 validates方法中使用 message选项来指定它。

length
class Person < ApplicationRecord  validates :name, length: { minimum: 2 }  validates :bio, length: { maximum: 500 }  validates :password, length: { in: 6..20 }  validates :registration_number, length: { is: 6 }end

这段代码是一个 Rails 应用程序中的 ActiveRecord 模型类,它用于定义一个名为 Person的类,并对其中的几个属性进行验证。

在这个例子中,validates方法用于为 namebiopasswordregistration_number属性添加验证规则。具体来说:

validates :name, length: { minimum: 2 }表示要验证 name属性的长度是否至少为 2 个字符。validates :bio, length: { maximum: 500 }表示要验证 bio属性的长度是否不超过 500 个字符。validates :password, length: { in: 6..20 }表示要验证 password属性的长度是否在 6 到 20 个字符之间。validates :registration_number, length: { is: 6 }表示要验证 registration_number属性的长度是否恰好为 6 个字符。

如果任何一个属性的值不符合指定的长度要求,则会在模型对象的 errors集合中添加一个错误消息。

在实际使用中,这些验证器可以用于确保用户输入的属性值符合预期的长度要求。例如,name属性可能需要至少包含两个字符,以确保姓名的有效性。bio属性可能需要限制在 500 个字符以内,以确保用户不会输入过长的自我介绍。password属性可能需要在安全性和易用性之间找到平衡,因此长度可能需要在一定范围内。registration_number属性可能需要确保长度恰好为 6 个字符,以确保准确性。

需要注意的是,这些验证器只是验证属性的长度,而不是内容。如果需要对属性的内容进行验证,可以使用其他类型的验证器,例如 presenceformat等。

默认错误消息取决于正在执行的长度验证的类型。您可以使用:wrong_length、:too_long和:too_short选项定制这些消息,并使用%{count}作为与所使用的长度约束相对应的数字的占位符。您仍然可以使用:message选项来指定错误消息

class Person < ApplicationRecord  validates :bio, length: { maximum: 1000,    too_long: "%{count} characters is the maximum allowed" }end
numericality数值
class Player < ApplicationRecord  validates :points, numericality: true  validates :games_played, numericality: { only_integer: true }end

这段代码是一个 Rails 应用程序中的 ActiveRecord 模型类,它用于定义一个名为 Player的类,并对其中的 pointsgames_played属性进行验证。

在这个例子中,validates方法用于为 points属性添加一个验证规则。具体来说,使用了 numericality选项,表示要验证属性的值是否为数值类型。这个验证器将确保 points属性的值包含一个有效的数值。例如,如果 points的值为 "123" 或 "123.45",则验证将通过,但如果 points的值为 "abc" 或 "123abc",则验证将失败。

在第二个验证器中,同时通过了 numericalityonly_integer选项,表示要验证 games_played属性的值是否为整数类型。这个验证器将确保 games_played属性的值为一个整数。例如,如果 games_played的值为 "123",则验证将通过,但如果 games_played的值为 "123.45" 或 "abc",则验证将失败。

需要注意的是,这些验证器只是验证属性的值是否为数值类型或整数类型,而不是具体的值是否符合特定的条件。如果需要对属性的值进一步验证,可以使用其他类型的验证器,例如 inclusionexclusionlengthformat等。

在实际应用中,这些验证器可以用于确保 Player对象的 pointsgames_played属性包含有效的数值或整数类型的值。如果验证失败,则会在模型对象的 errors集合中添加一个错误消息。这个错误消息的默认内容为 "is not a number" 或 "must be an integer",具体内容取决于验证器的选项。如果需要自定义错误消息,可以像我在之前的回答中所述那样使用 message选项。

这些选项是用于 numericality验证器的子选项,用于进一步验证属性的值是否符合特定的条件,具体说明如下:

greater_than- 指定属性的值必须大于指定的值。默认错误消息为 "must be greater than %{count}"。greater_than_or_equal_to- 指定属性的值必须大于或等于指定的值。默认错误消息为 "must be greater than or equal to %{count}"。equal_to- 指定属性的值必须等于指定的值。默认错误消息为 "must be equal to %{count}"。less_than- 指定属性的值必须小于指定的值。默认错误消息为 "must be less than %{count}"。less_than_or_equal_to- 指定属性的值必须小于或等于指定的值。默认错误消息为 "must be less than or equal to %{count}"。other_than- 指定属性的值必须不等于指定的值。默认错误消息为 "must be other than %{count}"。in- 指定属性的值必须在指定的范围内。默认错误消息为 "must be in %{count}"。odd- 如果设置为 true,则指定属性的值必须是奇数。默认错误消息为 "must be odd"。even- 如果设置为 true,则指定属性的值必须是偶数。默认错误消息为 "must be even"。

这些选项可以与其他验证器组合使用,以进一步验证属性的值是否符合特定的条件,并提供自定义错误消息。例如,可以使用以下验证器验证属性的值是否为正数:

validates :number, numericality: { greater_than: 0, message: "must be a positive number" }

如果属性的值不是正数,则会在模型对象的 errors集合中添加一个错误消息,内容为 "must be a positive number"。这样可以帮助开发者更好地控制数据的有效性,提高应用程序的稳定性和可靠性。

presence验证为空
class Person < ApplicationRecord  validates :name, :login, :email, presence: trueend

这段代码是一个 Rails 应用程序中的 ActiveRecord 模型类,它用于定义一个名为 Person的类,并对其中的 nameloginemail属性进行验证。

在这个例子中,validates方法用于为 nameloginemail属性添加一个验证规则。具体来说,使用了 presence选项,表示要验证属性的值是否存在,即不能为空值或空字符串。这个验证器将确保 nameloginemail属性的值都不为空。如果其中任何一个属性的值为空,则验证将失败。

需要注意的是,presence验证器只是验证属性的值是否存在,而不是具体的值是否符合特定的条件。如果需要对属性的值进一步验证,可以使用其他类型的验证器,例如 lengthformatinclusionexclusion等。

在实际应用中,这些验证器可以用于确保 Person对象的 nameloginemail属性都不为空。如果验证失败,则会在模型对象的 errors集合中添加一个错误消息。这个错误消息的默认内容为 "can"t be blank",表示属性的值不能为空。如果需要自定义错误消息,可以像我在之前的回答中所述那样使用 message选项。

absence
class Person < ApplicationRecord  validates :name, :login, :email, absence: trueend

这段代码是一个 Rails 应用程序中的 ActiveRecord 模型类,它用于定义一个名为 Person的类,并对其中的 nameloginemail属性进行验证。

在这个例子中,validates方法用于为 nameloginemail属性添加一个验证规则。具体来说,使用了 absence选项,表示要验证属性的值是否不存在,即必须为 nil或空字符串。这个验证器将确保 nameloginemail属性的值都不存在。如果其中任何一个属性的值不为空,则验证将失败。

需要注意的是,absence验证器与 presence验证器相反。presence验证器用于验证属性的值是否存在,而absence验证器用于验证属性的值是否不存在。这两个验证器都是用于确保属性的值符合预期,并且避免了数据不一致的情况。

在实际应用中,这些验证器可以用于确保 Person对象的 nameloginemail属性都不存在。如果验证失败,则会在模型对象的 errors集合中添加一个错误消息。这个错误消息的默认内容为 "must be blank",表示属性的值必须为空。如果需要自定义错误消息,可以像我在之前的回答中所述那样使用 message选项。

uniqueness唯一性
class Account < ApplicationRecord  validates :email, uniqueness: trueend

这段代码是一个 Rails 应用程序中的 ActiveRecord 模型类,它用于定义一个名为 Account的类,并对其中的 email属性进行验证。

在这个例子中,validates方法用于为 email属性添加一个验证规则。具体来说,使用了 uniqueness选项,表示要验证属性的值是否唯一。这个验证器将确保 email属性的值在整个 Account表中都是唯一的。如果有多个 Account对象具有相同的 email属性值,则验证将失败。

需要注意的是,uniqueness验证器用于确保属性的值在整个表中是唯一的,它不会验证属性的值是否存在。如果需要同时验证属性的存在性,可以在验证器链中使用 presence验证器。

在实际应用中,这个验证器可以用于确保 Account对象的 email属性是唯一的。如果验证失败,则会在模型对象的 errors集合中添加一个错误消息。这个错误消息的默认内容为 "has already been taken",表示属性的值已经被占用了。如果需要自定义错误消息,可以像我在之前的回答中所述那样使用 message选项。

validates_with自定义验证器

validates_with是 ActiveRecord 模型类中的一个方法,它用于将自定义验证器添加到模型类中,以验证模型对象的属性。

使用 validates_with方法可以将自定义验证器添加到模型类中,例如:

class Person < ApplicationRecord  validates_with GoodnessValidatorend

在这个例子中,我们将 GoodnessValidator自定义验证器添加到 Person模型类中。当我们在创建或更新 Person对象时,GoodnessValidator将会被调用,以验证 Person对象的属性。

需要注意的是,validates_with方法和其他内置验证方法(如 validates_presence_ofvalidates_uniqueness_of等)有所不同,它不会自动添加错误消息到模型对象的 errors集合中。相反,自定义验证器需要自行处理错误消息的添加。

在自定义验证器的 validate方法中,我们可以使用 record.errors.add方法将错误消息添加到模型对象的 errors集合中。例如:

class GoodnessValidator < ActiveModel::Validator  def validate(record)    if record.first_name == "Evil"      record.errors.add :base, "This person is evil"    end  endend

在这个示例中,如果 Person对象的 first_name属性为 "Evil",则会在模型对象的 errors集合中添加一个错误消息,指示此人是邪恶的。

因此,使用 validates_with方法需要自定义验证器开发人员具备一定的 Ruby 编程知识和技能,以确保验证器能够正确地处理错误消息的添加和其他验证逻辑。

validates_each
class Person < ApplicationRecord  validates_each :name, :surname do |record, attr, value|    record.errors.add(attr, "must start with upper case") if value =~ /\A[[:lower:]]/  endend

这段代码定义了一个 Person模型类,并使用 validates_each方法为 namesurname两个属性添加了一个自定义验证器。

validates_each方法是一个 Rails 提供的方法,它允许我们为指定的属性添加自定义验证器代码块。在这个例子中,我们使用了 validates_each方法并传入两个参数 namesurname,这意味着我们将为这两个属性添加自定义验证器。

自定义验证器代码块中的第一个参数 record是当前正在验证的模型对象。第二个参数 attr是当前正在验证的属性名称,第三个参数 value是当前属性的值。

在这个例子中,我们使用了一个正则表达式 /\A[[:lower:]]/来检查属性值是否以小写字母开头。如果是,我们就在模型对象的 errors数组中添加一个错误消息,以通知用户该属性必须以大写字母开头。

需要注意的是,使用 validates_each方法允许我们为属性添加更加复杂的自定义验证逻辑,而不仅仅是简单的比较或格式验证。然而,需要注意的是,由于自定义验证器是在每次验证时被调用的,因此如果验证逻辑较为复杂,它可能会对性能产生一定的影响。

标签: