Date validation

Has anyone ever tweaked the standard date controls to ban dates like
30th february ?

As standard, if you enter 30th february , it goes through quietly (no
errors) as 2nd march.

I’ve rummaged around in the source code, but so far I’ve been unable to
discover the process that magically transforms the six separate bits of
a form date-time field back into a single date when the form is
submitted. I’d guess that finding that process is key to fixing the
problem.

TIA, Andy

I just use the standard library’s date validation
within the model’s validate method.


– Tom M.

rails nut writes:

Has anyone ever tweaked the standard date controls to ban dates like
30th february ?

As standard, if you enter 30th february , it goes through quietly (no
errors) as 2nd march.

Tom M. <tmornini@…> writes:

I just use the standard library’s date validation
within the model’s validate method.

If Rails automatically converts a ‘bad’ date into it’s equivalent ‘good’
date, wouldn’t the model’s validation method always see a valid date?
At what
point in the object’s life cycle does ‘Feb 30’ or ‘June 31’ get
translated
into ‘March 2’ and ‘July 1’?

From the descriptions, it seems that rails nut’s app is happily chugging along
when weird dates are entered, while Tom’s models raise a validation
error. I’m
assuming, of course, that if rails nut added date validation to the
method, it
would also barf on a weird date, meaning that validation is the way to
handle
this issue. However, if the bad dates go through even with validation,
then
that is something different…

…Isn’t it? I’m a n00b t00, so this is more of a “verifiying my
knowledge”
than a “this is the answer.”

To clarify what’s happening:

User has a form to create new object which has scaffolded code for a
date field. User selects feb 30th and hits submit on the form. New
object is created by rails with no validation errors, but the date comes
back as march 2nd.

I would like feb 30th to raise an error somehow, preferably in
validation at the model layer, but I haven’t yet found out how to do
date validation.

Andy

Open up ActiveRecord::Base and look for the attribute= method. Its
starts
there.

Bob

Tom M. wrote:

I just use the standard library’s date validation
within the model’s validate method.


– Tom M.

I can’t see anything for date validation in the rails book or the ruby
book. Can you tell me what you mean by ‘standard library date
validation’ please ?

Andy

On Jan 31, 2006, at 2:20 AM, rails nut wrote:

Tom M. wrote:

I just use the standard library’s date validation
within the model’s validate method.


– Tom M.

I can’t see anything for date validation in the rails book or the ruby
book. Can you tell me what you mean by ‘standard library date
validation’ please ?

Sorry for the long delay on this.

The talk of Rails returning dates that don’t match the
input rather surprised me. I’ve been working on tests
and backend work almost exclusively, so I wanted to
investigate this for myself completely before discussing
it further.

OK, I have a form that allows date input, and on submit
I get this in the logs:

Parameters: {“buyer”=>{“born_on(1i)”=>“1988”,“born_on
(2i)”=>“2”,“born_on(3i)”=>“31”}, “commit”=>“Create”}

I can access the buyer.born_on field, as you’ve been discussing, but
I can also access:

params[:buyer][‘born_on(1i)’] -> 1988
params[:buyer][‘born_on(2i)’] -> 2
params[:buyer][‘born_on(3i)’] -> 31

Which can be tested with this application.rb method:

def test_date(object,attribute)
Date.valid_civil?(params[object][attribute + ‘(1i)’].to_i,
params[object][attribute + ‘(2i)’].to_i,
params[object][attribute + ‘(3i)’].to_i)
end

by writing:

def valid
test_date(:buyer,‘born_on’)
end


– Tom M.

Tom M. wrote:

Which can be tested with this application.rb method:

def test_date(object,attribute)
Date.valid_civil?(params[object][attribute + ‘(1i)’].to_i,
params[object][attribute + ‘(2i)’].to_i,
params[object][attribute + ‘(3i)’].to_i)
end

by writing:

def valid
test_date(:buyer,‘born_on’)
end


– Tom M.

That’s pretty close to what I did in the end, except your code
parameterises the field name to be checked, and I manually wrote the
bans on feb 30 etc ('cos I didn’t know date.valid_civil? existed).

I will probably re-factor based on your code … many thanks.

Andy

Was there any ever resolution with this? I am having the same exact
problem and would really prefer to not have to put validation logic in
my controller.

Sean

But that only lets you validate the date at the controller level. What
if you want to perform validation at the model level, and from what I
gather is the Rails way of doing things?

The point the previous posters have been making is that by the time the
date is available for validation in the model it has already been
coerced into a valid format by rails so any attempt to validate it will
succeed.

I’ve put together a simple form that contains among other things a
date_select:

<%= date_select(:user, :dob, :order => [:day, :month, :year],
:start_year => 1900, :end_year => Date.today.year) %>

In my controller I have some code to create a user entity from the
parameters posted up from the form, like so:

parameters: {“user”=>{“dob(1i)”=>“2006”, “dob(2i)”=>“2”,
“dob(3i)”=>“31”}}

@user = User.new(params[:user])

As if by magic Rails will convert dates like 31/02/2006 into 03/03/2006
so at the model level ‘user.dob’ => ‘03/03/2006’.

Are you supposed to refrain from constructing model objects using the
above technique when dates are involved?

regards,
Cathal.

Tom M. wrote:

On Jan 31, 2006, at 2:20 AM, rails nut wrote:

Tom M. wrote:

I just use the standard library’s date validation
within the model’s validate method.


– Tom M.

I can’t see anything for date validation in the rails book or the ruby
book. Can you tell me what you mean by ‘standard library date
validation’ please ?

Sorry for the long delay on this.

The talk of Rails returning dates that don’t match the
input rather surprised me. I’ve been working on tests
and backend work almost exclusively, so I wanted to
investigate this for myself completely before discussing
it further.

OK, I have a form that allows date input, and on submit
I get this in the logs:

Parameters: {“buyer”=>{“born_on(1i)”=>“1988”,“born_on
(2i)”=>“2”,“born_on(3i)”=>“31”}, “commit”=>“Create”}

I can access the buyer.born_on field, as you’ve been discussing, but
I can also access:

params[:buyer][‘born_on(1i)’] -> 1988
params[:buyer][‘born_on(2i)’] -> 2
params[:buyer][‘born_on(3i)’] -> 31

Which can be tested with this application.rb method:

def test_date(object,attribute)
Date.valid_civil?(params[object][attribute + ‘(1i)’].to_i,
params[object][attribute + ‘(2i)’].to_i,
params[object][attribute + ‘(3i)’].to_i)
end

by writing:

def valid
test_date(:buyer,‘born_on’)
end


– Tom M.