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?

Improve yourself with crontab and growlnotify

Its been a very long time since I last posted.  I’ve moved, changed jobs, major technologies (Windows / ASP.NET / C++ to Mac / Rails), had twin boys and am now working from home.  Working from home provides some great opportunities (family time instead of commute time being the big one).  I’ve found that I need help making sure that I take a break and step away from the computer occasionally during the day.  Also, I’m a skinny ex-cyclist who doesn’t like to go to the gym, but does want to be stronger.  Enter GrowlNotify and crontab to the rescue.


I use Growl and GrowlNotify for all sorts of things in my development work.  Anytime I kick off a long process (tests, database restore, etc), I use growlnotify to let me know that task is done.  That way, I don’t have to watch the process and can pick up immediately instead of possibly being distracted.

To provide me with a break every 30 minutes I’ve setup a cron job that sends me a message with growl.  Its very simple*:

~/.crontab

0,30 9-16 * * 1-5 /usr/local/bin/growlnotify -s -m “Time for some pushups or situps?” –image “/Users/johnnaegle/Pictures/growl_notify_pushup.jpg”

To let me easily change the timing, message or disable the notification easily, I put this in ~/.crontab (and some others) and added this to my .profile.  Whenever I launch a new terminal, the crontab gets updated with my latest list of timed notifications.
~/.profile

crontab < ~/.crontab

The result? I get a forced break (good for the eyes) and get stronger.  I’m already noticing a difference.
* every 30 minutes between 9am and 4pm on Monday through Friday, send me a sticky growl message with growl_notify_pushups.jpg as the icon.