Rails Validation Context

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

create時 update時にのみ走らせたいvalidationがある場合、下記のように on: :create on: :update で制御することができる。

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

バリデーションのタイミングを変更したい場合、on: :createを指定すればレコード新規作成時にのみ検証が行われ、on: :updateを指定すればレコードの更新時にのみ検証が行われます。

class Person < ApplicationRecord
  # 値が重複していてもemailを更新できる
  validates :email, uniqueness: true, on: :create

  # 新規レコード作成時に、数字でない年齢表現を使える
  validates :age, numericality: true, on: :update

  # デフォルト (作成時と更新時の両方でバリデーションを行なう)
  validates :name, presence: true
end

Custom Validation

create/update 以外の独自にvalidation context を定義することができる。

class Person < ApplicationRecord
  validates :email, uniqueness: true, on: :account_setup
  validates :age, numericality: true, on: :account_setup
end

person.valid?(:account_setup)は、モデルを保存せずにバリデーションを2つとも実行します。person.save(context: :account_setup)は、account_setupコンテキストでpersonをバリデーションしてから保存します。

新規作成

model = Model.new(model_params)
model.save(context: :custom)

更新時

attribute を更新した後に、Custom Validation を走らせつつ updateするパターン:

model = Model.find(id)
model.assign_attributes(model_params)
model.save(context: :custom)

Custom Validation を走らせた後に、updateするパターン:

model = Model.find(id)
if model.valid?(:custom)
  model.update(model_params)
end

参考. バリデーションを好きなときに実行する