3.Validation Options
3.1 :allow_nil
当验证值为nil时:allow_nil选项会跳过验证
class Coffee < ApplicationRecordvalidates :size, inclusion: { in: %w(small medium large),message: "%{value} is not a valid size" }, allow_nil: true
end
irb> Coffee.create(size: nil).valid?
=> true
irb> Coffee.create(size: "mega").valid?
=> false
3.1 :allow_blank
如果属性值为blank?,则跳过验证。
class Topic < ApplicationRecordvalidates :title, length: { is: 5 }, allow_blank: true
end
irb> Topic.create(title: "").valid?
=> true
irb> Topic.create(title: nil).valid?
=> true
irb> Topic.create(title: "short").valid?
=> false # 'short' is not of length 5, so validation fails even though it's not blank
3.3 :message
允许指定验证失败时添加到errors集合中的消息,否则,会使用默认错误消息。
class Person < ApplicationRecord# Hard-coded messagevalidates :name, presence: { message: "must be given please" }# Message with dynamic attribute value. %{value} will be replaced# with the actual value of the attribute. %{attribute} and %{model}# are also available.validates :age, numericality: { message: "%{value} seems wrong" }
end
Proc :message值有两个参数:正在验证的对象以及包含:model、:attribute 和 :value 键值对的hash。
class Person < ApplicationRecordvalidates :username,uniqueness: {# object = person object being validated# data = { model: "Person", attribute: "Username", value: <username> }message: ->(object, data) do"Hey #{object.name}, #{data[:value]} is already taken."end}
end
3.4 :on
on 选项允许你指定验证发生时间。默认情况下设置的验证会在save时运行,可以根据需要修改
class Person < ApplicationRecord# it will be possible to update email with a duplicated valuevalidates :email, uniqueness: true, on: :create# it will be possible to create the record with a non-numerical agevalidates :age, numericality: true, on: :update# the default (validates on both create and update)validates :name, presence: true
end
4. Conditional Validations
有时,只有在满足给定条件时才能验证对象,这可以通过:if 和 :unless 选项来实现。
class Order < ApplicationRecordvalidates :card_number, presence: true, if: :paid_with_card?def paid_with_card?payment_type == "card"end
end
或者
class Account < ApplicationRecordvalidates :password, confirmation: true,unless: Proc.new { |a| a.password.blank? }
end
:if 和 :unless也可以同时验证
class Computer < ApplicationRecordvalidates :mouse, presence: true,if: [Proc.new { |c| c.market.retail? }, :desktop?],unless: Proc.new { |c| c.trackpad.present? }
end
5 自定义验证
class Invoice < ApplicationRecordvalidate :expiration_date_cannot_be_in_the_past,:discount_cannot_be_greater_than_total_valuedef expiration_date_cannot_be_in_the_pastif expiration_date.present? && expiration_date < Date.todayerrors.add(:expiration_date, "can't be in the past")endenddef discount_cannot_be_greater_than_total_valueif discount > total_valueerrors.add(:discount, "can't be greater than total value")endend
end
6. 在视图中显示验证错误
定义模型并添加验证后,当通过网络表单创建model时验证失败,需要显示信息。
由于每个应用程序处理显示验证错误不同,因此Rails不包含任何用于生成这些信息的视图助手,需要自己写。比如:
<% if @article.errors.any? %><div id="error_explanation"><h2><%= pluralize(@article.errors.count, "error") %> prohibited this article from being saved:</h2><ul><% @article.errors.each do |error| %><li><%= error.full_message %></li><% end %></ul></div>
<% end %>