validatesメソッドでの条件指定

以前にも少し触れたActiveModelのvalidatesメソッドだが、以下のように個々のバリデーションに対して条件の指定ができる。

# password_required?がtrueの場合にpresenceのバリデーションが行われる
# confirmationのバリデーションはpassword_required?の結果に関わらず行われる
validates :password, presence: { if: :password_required? }, 
          confirmation: true

また、バリデーションに共通する条件も指定できる。

# password_required?がtrueの場合にpresenceとconfirmationのバリデーションが行われる
validates :password, presence: true, confirmation: true, 
          if: :password_required?

ただ、共通の条件と個々の条件で同じ種類のオプション("if:"や"on:"等)を使うと、 共通の条件が個々の条件で上書きされてしまうので注意。

# 以下のバリデーションの場合、presenseのバリデーションは行われるが、
# lengthのバリデーションは行われない。
validates :password, presence: { if: "true" }, confirmation: true, 
          if: "false"

なぜ、このようになっているのかはよく分からない。 そもそも共通の条件と個々の条件を同時に指定してはいけないのかもしれない。