1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

RailsのActive Modelで使える基本的なバリデーションまとめ

Last updated at Posted at 2019-09-05

はじめに

Railsで定義したモデルクラスには、Active Modelが提供する検証クラスによって様々なバリデーションを宣言することができます。
ユーザーからの入力をシンプルなコードで検証できる大変便利な機能なのですが、使用する度に忘れてしまうので、基本的なものだけでも覚えるために記事に起こしておきます。

注意:以下、Rails 5系をベースにした内容になります

検証対象の作成

何はともあれ検証対象となるモデルが必要になるので、Rails newからのscaffoldでUserモデルをサクッと作成します。

$ rails new validation_test
$ rails g scaffold User name:string age:integer group:string email:string

バリデーションの宣言

バリデーションは、モデルクラスにvalidatesメソッドを記述することで定義できます。
まずは、先ほど作成したUserモデルのnameカラムに存在性のバリデーションを定義してみます。

class User < ApplicationRecord
  validates :name, presence: true
end

validatesメソッドは、第一引数に検証対象のフィールド名、第二引数に検証ルール名とそのパラメーターのハッシュをとります。(presenceルールにはパラメーターがないため、単にtrueとのみ記載する)

この状態でUserモデルの新規作成・更新などを行おうとした時、いずれかのフィールドが空だとエラーが発生します。

スクリーンショット 2019-09-06 0.22.13.png

デフォルトでは、このようにエラーメッセージの表示ととフォームの強調表示をしてくれます。

検証するフィールドは、以下のように一度に複数個指定することも可能です。

class User < ApplicationRecord
  validates :name, :email, :age, :group,  presence: true
end

また、後述するlength検証などと合わせて、一度に複数の検証を宣言する場合は以下のように記述します。

class User < ApplicationRecord
  validates :name, presence: true, length: { is: 5 }, uniqueness: true
end

バリデーションが機能するタイミング

バリデーションはレコードの新規作成・更新の際に機能すると書きましたが、具体的には以下のメソッドを実行しようとした時点で検証が行われます。

  • create, create!
  • save, save!
  • update, update!

これら以外の、例えばincrement!toggle!update_attributeなどのメソッドを使用した際には、定義したバリデーションが機能せずにそのままDBに書き込まれてしまいます。
そのため、検証が不要なフィールドや事前に何らかの検証が行われているといった場合以外では、可能な限り上記のメソッドを使った方が安全です。

また、モデルオブジェクトに対してvalid?メソッドを用いると、DBへの保存とは関係なくオブジェクトがvalidな状態かどうかを真偽値で返してくれます。

様々な検証機能

先に挙げたpresence検証以外にも、Railsには多くの検証機能が存在します。

非存在性の検証

absence検証を用いると、値が空であるかどうかの認証ができます。特定の条件下では入力されたくないフィールドがある場合に使えますね。

# groupフィールドへの入力を禁止する
validates :group, absence: true

文字列長の検証(length)

length検証を使用すると、入力された文字列の長さのチェックを行ってくれます。
指定できるパラメーターには、最小の長さを定めるminimum、逆に最大の長さを定めるmaximumなどがあります。

# 最長文字数を10文字に設定する
validates :name, length: { maximum: 10 }

# 最小文字数を10文字に設定する
validates :name, length: { minimum: 3 }

# 最小・最大文字数を同時に検証する
validates :name, length: { maximum: 10, minimum: 3 }

# ぴったり5文字の文字列のみ許可する
validates :name, length: { is: 5 }

数値の検証(numericalcality)

numericalcality検証を宣言すると、数値入力が期待されるフィールドに対して数値チェックや大小チェックなどが行えます。

# 入力値が数値かどうかを検証する
validates :age, numericality: true

# 入力値が整数かどうかを検証する
validates :age, numericality: { only_integer: true }

# 指定した値よりも大きいかどうか
validates :age, numericality: { greater_than: 5 }

# 指定した値以上かどうか
validates :age, numericality: { greater_than_or_equal_to: 5 }

# 指定した値よりも小さいかどうか
validates :age, numericality: { less_than: 100 }

# 指定した値以下かどうか
validates :age, numericality: { less_than_or_equal_to: 100 }


# 指定した値と同値かどうか
validates :age, numericality: { equal_to: 20 }

# 奇数かどうか
validates :age, numericality: { odd: true }

# 偶数かどうか
validates :age, numericality: { even: true }

範囲内 or 範囲外の検証(inclusion/exclusion)

inclusion検証を使用すると、値が指定のリストの中に含まれるか、もしくは指定の範囲に含まれるかどうかを検証できます。
対してexclusion検証を使用すると、値が指定のリストの中に含まれていないか、もしくは指定の範囲に含まれていないかどうかを検証できます。
ホワイトリスト、ブラックリストの定義に使えますね。

# 入力値がA, B, Cのいずれかの文字列であるかどうか
validates :group, inclusion: { in: %w[A B C] }

# 同じ内容を範囲オブジェクトで指定することもできる
validates :group, inclusion: { in: ('A'..'C') }

# exclusionはinclusionの逆
validates :group, exclusion: { in: %w[A B C] }
validates :group, exclusion: { in: ('A'..'C') }

正規表現による検証(format)

format検証を用いると、入力された文字列が指定した正規表現にマッチするかどうかの検証を行えます。正規表現はwithパラメーターの値として指定します。
emailなど、一定のパターンに当てはまる値を期待する場合に指定することになるかと思います。

# 入力値がA, B, Cのいずれかの文字列であるかどうか(inclusionの例と同じ)
validates :group, format: { with: /\A[ABC]\Z/ }

# emailの形式かどうかチェックする
email_regex = /\A[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*\Z/
validates :email, format: { with: email_regex }

ユニークネス検証(uniqueness)

uniqueness検証を用いると、入力値がそのフィールドにおいて一意なものかどうかの検証を行ってくれます。重複を許さないデータ、例えばメールアドレスなどの検証に使えるかと思います。
オプションとして、パラメーターのcase_sensitiveを使用すると、大文字・小文字の区別を行うかどうかを設定できます。(デフォルトでは有効(true)。)

また、2つ以上のフィールドの組み合わせにおいて一意になるようにしたい!という場合は、パラメーターにscopeを使用することで実現できます。

# メールアドレスの一意性を検証する
validates :email, uniqueness: true

# 大文字・小文字の区別を行わない
validates :email, uniqueness: { case_sensitive: false }

# グループごとにメールアドレスの一意性を検証する
validates :email, uniqueness: { scope: :group }

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?