LoginSignup
86
68

More than 5 years have passed since last update.

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

Posted at

ifを使用した条件分岐

例えば、bという項目がtrueの場合のみaの値は必須にしたい、とかあると思う。
if: オプションを使えばいいのだけれど、複数バリデーションまとめて判定させたい場合は、
with_optionsメソッドを使用して以下のように実装することができる。

post.rb
class Post < ActiveRecord::Base
  # ifオプションで条件に合致する場合のみvalidatesを実行(published?はメソッド名またはmodelのboolean項目)
  validates :name, presence: true if: published?

  # 複数valitatesをまとめたい場合はwith_optionsを使用
  with_options if: :published? do
    validates :name,  presence: true
    validates :category,  presence: true
  end

  # unlessで条件に合致しない場合のみvalidatesを実行
  # lambdaを使うことで複数条件を指定できる
  with_options unless: -> { :hoge? || :foo? } do
    validates :name,  presence: true
  end
end

ただし、この場合、with_optionsブロック内部で更にif: を使用してしまうと、
内部のif条件の場合にしかvalidatesが実行されなくなる。

  # hogeの時しかwith_options内部が実行されない
  with_options if: :published? do
    validates :name,  presence: true
    validates :category,  presence: true, if: hoge
  end

  # with_optionsで定義したものと逆のもの(この場合はunless)を使用すれば問題ない
  with_options if: :published? do
    validates :name,  presence: true
    validates :category,  presence: true, unless: 'hoge.blank?'
  end

ネストしたvalidationを記載するなら、メソッドを一つ作って判定させた方が良さそう。

validates :name,  presence: true, if: :require_validation?

def require_validation?
  return true if aaa? && bbb?
  false
end

onを使用した条件分岐

例えば新規登録(create)の場合のみバリデーションをかけたい時は、onオプションを使用する。

post.rb
class Post < ActiveRecord::Base
  # createの時のみ実行
  validates :name, presence: true on: :create

  # if同様with_optionsでも指定できる
  with_options on: :create? do
    validates :name,  presence: true
    validates :category,  presence: true
  end

  # こうすることで、pattern_hogeコンテキストが渡された時のみvalidatesが実行される
  validates :hoge, presence: true, length: { maximum: 3000 }, on: :pattern_hoge
end
posts_controller.rb
class PostsController < ApplicationController
  def hoge
    # pattern_hogeコンテキストを指定
    post.save(context: :hoge.save(context: :pattern_validation))
  end
end
86
68
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
86
68