Ruby On Rails 笔记5——常用验证下

3.Validation Options

3.1 :allow_nil

当验证值为nil时:allow_nil选项会跳过验证

ruby 复制代码
class Coffee < ApplicationRecord
  validates :size, inclusion: { in: %w(small medium large),
    message: "%{value} is not a valid size" }, allow_nil: true
end
ruby 复制代码
irb> Coffee.create(size: nil).valid?
=> true
irb> Coffee.create(size: "mega").valid?
=> false

3.1 :allow_blank

如果属性值为blank?,则跳过验证。

ruby 复制代码
class Topic < ApplicationRecord
  validates :title, length: { is: 5 }, allow_blank: true
end
ruby 复制代码
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集合中的消息,否则,会使用默认错误消息。

ruby 复制代码
class Person < ApplicationRecord
  # Hard-coded message
  validates :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。

ruby 复制代码
class Person < ApplicationRecord
  validates :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时运行,可以根据需要修改

ruby 复制代码
class Person < ApplicationRecord
  # it will be possible to update email with a duplicated value
  validates :email, uniqueness: true, on: :create

  # it will be possible to create the record with a non-numerical age
  validates :age, numericality: true, on: :update

  # the default (validates on both create and update)
  validates :name, presence: true
end
4. Conditional Validations

有时,只有在满足给定条件时才能验证对象,这可以通过:if 和 :unless 选项来实现。

ruby 复制代码
class Order < ApplicationRecord
  validates :card_number, presence: true, if: :paid_with_card?

  def paid_with_card?
    payment_type == "card"
  end
end

或者

ruby 复制代码
class Account < ApplicationRecord
  validates :password, confirmation: true,
    unless: Proc.new { |a| a.password.blank? }
end

:if 和 :unless也可以同时验证

ruby 复制代码
class Computer < ApplicationRecord
  validates :mouse, presence: true,
                    if: [Proc.new { |c| c.market.retail? }, :desktop?],
                    unless: Proc.new { |c| c.trackpad.present? }
end
5 自定义验证
ruby 复制代码
class Invoice < ApplicationRecord
  validate :expiration_date_cannot_be_in_the_past,
    :discount_cannot_be_greater_than_total_value

  def expiration_date_cannot_be_in_the_past
    if expiration_date.present? && expiration_date < Date.today
      errors.add(:expiration_date, "can't be in the past")
    end
  end

  def discount_cannot_be_greater_than_total_value
    if discount > total_value
      errors.add(:discount, "can't be greater than total value")
    end
  end
end
6. 在视图中显示验证错误

定义模型并添加验证后,当通过网络表单创建model时验证失败,需要显示信息。

由于每个应用程序处理显示验证错误不同,因此Rails不包含任何用于生成这些信息的视图助手,需要自己写。比如:

ruby 复制代码
<% 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 %>
相关推荐
Baklib梅梅3 天前
2025 年 8 个最佳网站内容管理系统(CMS)
前端·ruby on rails·前端框架·ruby
Gavin_91518 天前
从零开始部署经典开源项目管理系统最新版redmine6-Linux Debian12
linux·ruby on rails·开源·debian·ruby·redmine
Baklib梅梅2 个月前
Ruby大会演讲实录:Baklib 如何用 AI 重构内容管理赛道
ruby on rails·前端框架·ruby
Baklib梅梅2 个月前
Baklib作为赞助商参加RubyConf China 2025 技术大会
ruby on rails
JalenYan6 个月前
Ruby on Rails 中的 Delegated Types(委托类型)
后端·ruby on rails·ruby
微信-since811926 个月前
[ruby on rails]ActiveModel源码阅读(Validations)
后端·ruby on rails
wuhuhuan6 个月前
Ruby基础
ruby on rails
fredricen8 个月前
使用VSCode搭建Ruby on Rails集成开发环境
ide·vscode·ruby on rails
haiyu柠檬9 个月前
Ruby On Rails 笔记4——常用验证上
ruby on rails