Weird Rails validates behaviour

I’m working on an application to maintain a set of temporary access accounts with some custom validators in the model (I summarise),

has_one :account_type
 validates :account_type_id, :presence => true, allow_blank: false
 validates :firstname, :surname, :uid, :passwd, :expiry_date, :owner, :presence => true
 validate :expiry_date_cannot_too_far_in_future
def expiry_date_cannot_too_far_in_future
  ed = AccountType.max_expiry?(account_type_id)
  if expiry_date > ed
    atn = AccountType.account_type_name(account_type_id)
    errors.add(:expiry_date, "can't exceed #{atn} account type limit of #{ed.to_s(:my_date)}.")
  end
 end

I also have a generic trap in my application_controller to rescue_from ActiveRecord::RecordNotFound with a flash error message.

But when using the site and forgetting to set the (required) account_type, I was returning to the index page with flash error rather than re-displaying the form and highlighting the missing field, despite the validator. Very odd.

A little bit of digging around and I realised the culprit being the ‘expiry_date_cannot_too_far_in_future’ validator which ist calling AccountType methods without an account_type_id value which generates the exception which is handled by the application_controller.

Two things to do here:

  1. Update the AccountType methods to return nil on RecordNotFound (which would have thrown a nil comparison error in the validator highlighting where the problem was)
  2. Add return false if ! account_type_id to the custom validator to prevent the exception being thrown in the first place.
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s