关于Validation的方法使用
acceptance验证
acceptance
是 Rails 中的一个验证器(validator),用于验证一个布尔类型的属性是否被接受。在表单中,通常会有一些复选框或单选按钮,用户需要勾选或选择才能提交表单。acceptance
验证器用于确保这些复选框或单选按钮已经被选中或勾选。
当一个属性被验证时,acceptance
验证器会检查该属性是否为 true。如果为 true,则验证通过;否则,验证失败,并将错误信息添加到模型对象的 errors
集合中。
例如,在下面的代码中,acceptance
验证器用于验证 terms_of_service
属性是否被接受:
class Person < ApplicationRecord
validates :terms_of_service, acceptance: true
end
在这个例子中,如果一个 Person
对象的 terms_of_service
属性没有被设置为 true,那么该对象就无法通过验证,并且会在 errors
集合中添加一个名为 terms_of_service
的错误信息。
在表单中,可以使用 Rails 提供的 check_box
或 radio_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 :books
end
这段代码是一个 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: true
end
这段代码是一个 Rails 应用程序中的 ActiveRecord 模型类,它用于定义一个名为 Person
的类,并对其中的 email
属性进行验证。
在这个例子中,validates
方法用于为 email
属性添加验证规则。具体来说,使用了 confirmation
选项,表示需要对 email
属性进行确认验证。这意味着在表单中提交时,除了输入 email
属性的值之外,还需要再次输入相同的值,以便验证两次输入的值是否一致。如果两次输入的值不一致,则会在模型对象的 errors
集合中添加一个名为 email_confirmation
的错误信息。
需要注意的是,confirmation
验证器只适用于需要确认的属性,例如密码和电子邮件地址等。如果要对其他类型的属性进行验证,可以使用其他的验证器来实现。
class Person < ApplicationRecord
validates :email, confirmation: true
validates :email_confirmation, presence: true
end
这段代码是一个 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
属性的值为 "[email protected]",则确认验证器会接受 "[email protected]" 或其他任何大小写组合的电子邮件地址作为有效值。
需要注意的是,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_date
和 end_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_date
和 end_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
方法用于为 name
、bio
、password
和 registration_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 个字符,以确保准确性。
需要注意的是,这些验证器只是验证属性的长度,而不是内容。如果需要对属性的内容进行验证,可以使用其他类型的验证器,例如 presence
、format
等。
默认错误消息取决于正在执行的长度验证的类型。您可以使用: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
的类,并对其中的 points
和 games_played
属性进行验证。
在这个例子中,validates
方法用于为 points
属性添加一个验证规则。具体来说,使用了 numericality
选项,表示要验证属性的值是否为数值类型。这个验证器将确保 points
属性的值包含一个有效的数值。例如,如果 points
的值为 "123" 或 "123.45",则验证将通过,但如果 points
的值为 "abc" 或 "123abc",则验证将失败。
在第二个验证器中,同时通过了 numericality
和 only_integer
选项,表示要验证 games_played
属性的值是否为整数类型。这个验证器将确保 games_played
属性的值为一个整数。例如,如果 games_played
的值为 "123",则验证将通过,但如果 games_played
的值为 "123.45" 或 "abc",则验证将失败。
需要注意的是,这些验证器只是验证属性的值是否为数值类型或整数类型,而不是具体的值是否符合特定的条件。如果需要对属性的值进一步验证,可以使用其他类型的验证器,例如 inclusion
、exclusion
、length
、format
等。
在实际应用中,这些验证器可以用于确保 Player
对象的 points
和 games_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: true
end
这段代码是一个 Rails 应用程序中的 ActiveRecord 模型类,它用于定义一个名为 Person
的类,并对其中的 name
、login
和 email
属性进行验证。
在这个例子中,validates
方法用于为 name
、login
和 email
属性添加一个验证规则。具体来说,使用了 presence
选项,表示要验证属性的值是否存在,即不能为空值或空字符串。这个验证器将确保 name
、login
和 email
属性的值都不为空。如果其中任何一个属性的值为空,则验证将失败。
需要注意的是,presence
验证器只是验证属性的值是否存在,而不是具体的值是否符合特定的条件。如果需要对属性的值进一步验证,可以使用其他类型的验证器,例如 length
、format
、inclusion
、exclusion
等。
在实际应用中,这些验证器可以用于确保 Person
对象的 name
、login
和 email
属性都不为空。如果验证失败,则会在模型对象的 errors
集合中添加一个错误消息。这个错误消息的默认内容为 "can't be blank",表示属性的值不能为空。如果需要自定义错误消息,可以像我在之前的回答中所述那样使用 message
选项。
absence
class Person < ApplicationRecord
validates :name, :login, :email, absence: true
end
这段代码是一个 Rails 应用程序中的 ActiveRecord 模型类,它用于定义一个名为 Person
的类,并对其中的 name
、login
和 email
属性进行验证。
在这个例子中,validates
方法用于为 name
、login
和 email
属性添加一个验证规则。具体来说,使用了 absence
选项,表示要验证属性的值是否不存在,即必须为 nil
或空字符串。这个验证器将确保 name
、login
和 email
属性的值都不存在。如果其中任何一个属性的值不为空,则验证将失败。
需要注意的是,absence
验证器与 presence
验证器相反。presence
验证器用于验证属性的值是否存在,而absence
验证器用于验证属性的值是否不存在。这两个验证器都是用于确保属性的值符合预期,并且避免了数据不一致的情况。
在实际应用中,这些验证器可以用于确保 Person
对象的 name
、login
和 email
属性都不存在。如果验证失败,则会在模型对象的 errors
集合中添加一个错误消息。这个错误消息的默认内容为 "must be blank",表示属性的值必须为空。如果需要自定义错误消息,可以像我在之前的回答中所述那样使用 message
选项。
uniqueness唯一性
class Account < ApplicationRecord
validates :email, uniqueness: true
end
这段代码是一个 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 GoodnessValidator
end
在这个例子中,我们将 GoodnessValidator
自定义验证器添加到 Person
模型类中。当我们在创建或更新 Person
对象时,GoodnessValidator
将会被调用,以验证 Person
对象的属性。
需要注意的是,validates_with
方法和其他内置验证方法(如 validates_presence_of
、validates_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
end
end
在这个示例中,如果 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:]]/
end
end
这段代码定义了一个 Person
模型类,并使用 validates_each
方法为 name
和 surname
两个属性添加了一个自定义验证器。
validates_each
方法是一个 Rails 提供的方法,它允许我们为指定的属性添加自定义验证器代码块。在这个例子中,我们使用了 validates_each
方法并传入两个参数 name
和 surname
,这意味着我们将为这两个属性添加自定义验证器。
自定义验证器代码块中的第一个参数 record
是当前正在验证的模型对象。第二个参数 attr
是当前正在验证的属性名称,第三个参数 value
是当前属性的值。
在这个例子中,我们使用了一个正则表达式 /\A[[:lower:]]/
来检查属性值是否以小写字母开头。如果是,我们就在模型对象的 errors
数组中添加一个错误消息,以通知用户该属性必须以大写字母开头。
需要注意的是,使用 validates_each
方法允许我们为属性添加更加复杂的自定义验证逻辑,而不仅仅是简单的比较或格式验证。然而,需要注意的是,由于自定义验证器是在每次验证时被调用的,因此如果验证逻辑较为复杂,它可能会对性能产生一定的影响。