Railsで特定のアクションのみバリデーションをかけたい

FBCRailsのdeviseのプラクティスで特定のアクションのみバリデーションをかけたかったので方法を調べました。

結論

特定のアクションのみバリデーションをかけるにはon: オプションでアクションを指定する。

バリデーションはデフォルトでレコード作成、更新の両方で実行されるようです。

ビルトインのバリデーションヘルパーは、デフォルトでは保存時(レコードの作成時および更新時の両方)に実行されます。

これをアクション毎に動作させたい場合は下記の用にon: オプションを指定すればokです。

  • レコード作成時のみ: on: :create
  • レコード更新時のみ: on: :update

ちなみにon: アクションはHTTPメソッドだけでなく独自のメソッドを指定することもできます。

Active Record バリデーション - Railsガイド

実装例

usersテーブルの郵便番号を保存するzipcode カラムに7桁整数指定のバリデーションをレコード更新時のみ動作させる。

# frozen_string_literal: true

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  paginates_per 3
  # 末尾のon: 以降を追加
  validates :zipcode, length: { is: 7 }, numericality: { only_integer: true }, on: :update
end

これでレコード更新時のみバリデーションをかけることができました。

まとめ

思ったよりすぐに解決できてよかった。 バリデーション周りはフワフワした理解しかないのでたくさん触っていこう。

参照

Railsで特定の条件下で走るバリデーションを作りたい - Qiita

Active Record バリデーション - Railsガイド