Validation conundrum with Dates

Hi guys.

I have a very interesting validation problem.

Say I have a model defined called Event, and this model has a field
:event_date (for illustration, we could assume it’s the only field aside
from id) that is defined as a Date type.

I want to allow this field to either be a valid date of a format of my
choosing (\d{4}-\d{1,2}-\d{1,2}), or nil.

In other to validate, I need to use validates_format_of or a custom
validate
method. validates_format_of.

Since the field could already (and validly) be nil, I decide to
implement a
custom check:

class Event < ActiveRecord::Base
def validate
if !event_date.nil? and event_date !~ /\d{4}-\d{1,2}-\d{1,2}/
errors.add(“event_date”, “is not formatted properly”)
end
end

So far so good, right? It appears that, if the user set event_date to
something, the regex will be tested and an error will be thrown if
event_date doesn’t match it.

HOWEVER, before validate is called, the event_date value (after being
set by
the action from its parameters) appears to have already been cast to a
Date,
which causing a string that can’t be handled by Date to be set to nil.
So,
now our first test, event_date.nil? fails and the regex is never
called…consequently, the user it not notified of the error. I have no
way
of getting at the parameter they passed here, so no way of knowing if
they
should indeed incur an error.

So…I need a boost. Can anyone tell me how they might accomplish this,
forcing a date to either be nil or formatted properly, while indicating
errors in formatting to the user?

Thanks a bunch!
Jake

how about using before_type_cast?

(untested):
if !event_date.nil? and event_date_before_type_cast !~
/\d{4}-\d{1,2}-\d{1,2}/

Jake C. wrote:

So…I need a boost. Can anyone tell me how they might accomplish this,
forcing a date to either be nil or formatted properly, while indicating
errors in formatting to the user?

Try using validates_format_of with the :if param maybe?

validates_format_of :event_date, :with => /^\d{4}-\d{1,2}-\d{1,2}$/,
:if => lambda {|date| not date.nil?}

On 10/10/06, jemminger [email protected] wrote:

how about using before_type_cast?

(untested):
if !event_date.nil? and event_date_before_type_cast !~
/\d{4}-\d{1,2}-\d{1,2}/

Aha! Nice…and here I was trying event_date.before_type_cast…not
event_data_before_type_cast!

Thanks! I think I can make this work!

Jake

On 10/10/06, Jake C. [email protected] wrote:

Thanks! I think I can make this work!

It indeed works perfectly…thank you very much. I beat my head on this
deceptively simple thing for HOURS!!!

Best regards :wink:

Jake

This still won’t save you from dates such as 2006-02-30, and the like.

One common technique is to do something like:

def validate
d = Date.new(your_year_field, your_month_field, your_day_field)
rescue WhateverDateThrowsWhenItsNotValid => e
do_something_with_e.message
end

On 10/10/06, Jake C. [email protected] wrote:

Jake


If I can’t think of at least three different interpretations of what I
received, I haven’t thought enough about what it might mean. – Jerry
Weinberg