Friday, August 31, 2012

Validating a User's Age in Rails

We ran across an interesting bug in our application recently: a user who was 18 years old exactly could not sign up for our service.  This happened only in our production environment (not staging, development or test) and when we manually tested a number of dates, a user who was 18 years and 7 days old could sign up, but a user who was 18 years and 6 days old could not.

Here was our model validation:

user.rb validates_inclusion_of :birthdate, :in=>Date.new(1900)..Time.now.years_ago(18).to_date, :message=>'You must be 18 years or older'

The problem? That is cached when the server starts.  It turns out, we had last deployed to production 7 days ago.  We didn't see the problem in any other environments because they get restarted so frequently.

The solution is simple: use a proc that evaluates the current date each time:

user.rb validate :at_least_18

def at_least_18

    if self.birthdate
      errors.add(:birthdate, 'You must be 18 years or older.') if self.birthdate > 18.years.ago.to_date
    end
end

I'm still not sure how to test this, but it is working.

How would you test this?  Where else do you have to use a proc in Rails that won't show up locally?

No comments:

Post a Comment