0

I have the following three validations in a model in my rails app:

  validates_presence_of :reset_code, message: 'Please enter your reset code'
  validates_length_of :reset_code, is: 4, message: 'Your reset code should be 4 digits'
  validates_format_of :reset_code, with: /\A[0-9]{4}\z/, message: 'Please enter a valid reset code'

I only want to fire the second and third validations if the first is valid (as there is no point in telling the user the reset code isn't the correct length or format if they haven't entered one at all).

So something along the lines of:

validates_length_of :reset_code, is: 4, message: 'Your reset code should be 4 digits', :if => :reset_code.present?
Cameron
  • 27,963
  • 100
  • 281
  • 483

1 Answers1

1

You should use new the new validation syntax, and provide a simple if: condition:

  validates :reset_code, length: { is: 4 },
    message: 'Your reset code should be 4 digits',
    if: -> { reset_code.present? }

  validates :reset_code, format: { with: /\A[0-9]{4}\z/ },
    message: 'Please enter a valid reset code',
    if: -> { reset_code.present? }
user229044
  • 232,980
  • 40
  • 330
  • 338
  • Can I achieve this with the older syntax? – Cameron Jun 28 '16 at 15:36
  • @Cameron http://api.rubyonrails.org/classes/ActiveModel/Validations/HelperMethods.html – user229044 Jun 28 '16 at 15:37
  • Ah, it was because I had used `:if =>` rather than `if: ->` – Cameron Jun 28 '16 at 15:40
  • What if I want the third to only fire if the first and second have passed? So instead of checking if it is present, check the validation itself is valid? – Cameron Jun 28 '16 at 15:43
  • Could I just do: `if: -> { validates_length_of.valid? }` – Cameron Jun 28 '16 at 15:43
  • @Cameron The problem is that you're *doing* all three. Just do the `format` one. It makes no sense to validate the same field three times for the *same* data. Checking present *and* length *and* format is three times redundant. – user229044 Jun 28 '16 at 15:45