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 %>
相关推荐
fredricen1 个月前
使用VSCode搭建Ruby on Rails集成开发环境
ide·vscode·ruby on rails
haiyu柠檬2 个月前
Ruby On Rails 笔记4——常用验证上
ruby on rails
haiyu柠檬3 个月前
Ruby On Rails 笔记2——表的基本知识
数据库·笔记·ruby on rails
haiyu柠檬3 个月前
Ruby On Rails 笔记1——Rails 入门
笔记·ruby on rails
微信-since811923 个月前
【ruby on rails】dup、deep_dup、clone的区别
数据结构·后端·ruby on rails
微信-since811923 个月前
[ruby on rails] 安装docker
后端·docker·ruby on rails
江河湖海3 个月前
3. 用Ruby on Rails创建一个在线商城
后端·ruby on rails
yagas7 个月前
使用puma部署ruby on rails的记录
后端·ruby on rails
小筱在线7 个月前
如何在Linux上部署Ruby on Rails应用程序
linux·运维·ruby on rails