【Rails】バリデーションのタイミングを制御する方法

プログラミング

コンテキストを使うことで、任意のタイミングでバリデーションを行うことが出来ます。
つまり、バリデーションチェックのタイミングを制御することができるのです。

今回学習する内容は以下です。

  • 任意のタイミングでバリデーションをする方法
  • 逆に、任意のタイミングでバリデーションをしない方法

バリデーションコンテキストとは何なのか、また、どうやって使うのかを学習していきます。

任意のタイミングでバリデーションしたい要件

Ruby on Railsのバリデーションには、チェックしたいタイミングもあればチェックしたくないタイミングもあるかと思います。

例えば「データ新規登録の時だけバリデーションしたい」などがそれにあたります。

そんな時にコンテキストを使って、任意のタイミングでバリデーションすることができます。

※ある条件を満たした場合にバリデーションする方法もありますが、それはまた別記事で書こうと思います。ここでは、任意のタイミングでバリデーションすることを学びます。

バリデーションのコンテキストの定義方法

コンテキストはバリデーションの「:on オプション」を使用して定義します。

class User < ApplicationRecord
  validates :phone, uniqueness: true, on: :create
end

上記のように書けば、Userモデルを登録(create)するタイミングのみ、電話番号の重複チェックが行われます。

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

また、上記のように書けば、Userモデルを更新(update)するタイミングのみ、名前が入力されているかチェックが行われます。
登録の際はメールアドレスだけでよく、本登録を行う際は名前が必須入力などの場合です。

このように、バリデーションはコンテキストを定義することで、任意のタイミングでチェックできるのです。

自由度の高いカスタムコンテキスト

カスタムコンテキストを使うと、createやupdateに限らず、もっと自由なタイミングでバリデーションを行うこともできます。

class User < ApplicationRecord
  validates :name, presence: true, on: :signup
  validates :phone, numericality: true, on: :signup
end

上記の例では、コンテキストに「:signup」を定義しています。
カスタムコンテキストを持つバリデーションは、明示的に実行する必要があります。

user = User.new(name: '鈴木')
user.valid? # => true
user.valid?(context: :signup) # => false

それでは解説していきます。

user.valid? カスタムコンテキストを明示していないため、通常のバリデーションが行われます
user.valid?(context: :signup) 「:signup」が定義されたバリデーションのみ行われます

また、以下の書き方をすることで通常のバリデーション、カスタムコンテキストが定義されたバリデーションの両方を実行することができます。

user = User.new(name: '鈴木')
user.valid?(:signup) # => false

次回の更新は「Rubyでの正規表現について」書いていけたらと思います。