I was going to write something like that in a day or two. Will let you know
if I have any comments after using it.
-=- Neeraj
On 11/4/05, Peter Haight <peterh-a5ZtNvmu7UvQT0dZR+AlfA@public.gmane.org>
wrote:>
>
> I''ve had a bunch of issues with date validation and am starting to
wonder
> whether I''m missing the easy way to deal with them. Let''s
say I have an
> employees table with some date fields in it. I would like to do validation
> like this:
>
> class Employee < ActiveRecord::Base
> validates_presence_of :hire_date, :departure_date
> validates_date :hire_date, :departure_date
> end
>
> The first thing I realized was that there is no validates_date method. So
> I
> wrote one (it didn''t work):
>
> def validates_date(*attr_names)
> configuration = { :message => ''invalid date'' }
> configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
> validates_each(attr_names,configuration) do |record, attr_name, value|
> begin
> Date.parse(value.to_s)
> rescue ArgumentError
> record.errors.add(attr_name, configuration[:message])
> end
> end
> end
>
> The problem here is that any timestamp attribute gets typecast to a Time
> object and if that parsing fails, the error is silently ignored and the
> value
> for that attribute becomes nil. By the time we get to my validation
> method,
> the value is nil, so you can''t parse it. So instead of using
''value'' to
> parse, I do this to get the value before the type cast:
>
> value = record.send("#{attr_name}_before_type_cast")
>
> This still leaves the problem with validates_presence_of which will give
> you
> an error if the date is there but not valid. So I adjusted my
> validates_date
> to take an optional argument ''nil_ok'' which lets you say
whether the date
> can
> be blank or not. So it is finally working like I want, but I think there
> may
> be some fundamental problem in Rails of ignoring any errors that occur
> during
> attribute typecasting.
>
> What does everyone think?
>
>
> Here''s the final validator code, just in case anyone is
interested.
>
> module ActiveRecord
> module Validations
> module ClassMethods
> def validates_date(*attr_names)
> configuration = { :message => ''invalid date'', :nil_ok
=> true,
> :message_for_blank => "can''t be blank" }
> configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
> validates_each(attr_names,configuration) do |record, attr_name, value|
> begin
> value = record.send("#{attr_name}_before_type_cast")
> if value.strip == ''''
> if configuration.fetch(:nil_ok, true)
> next
> else
> record.errors.add(attr_name, configuration[:message_for_blank])
> next
> end
> end
> Date.parse(value.to_s)
> rescue ArgumentError
> record.errors.add(attr_name, configuration[:message])
> end
> end
> end
> end
> end
> end
>
> _______________________________________________
> Rails mailing list
> Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
>
_______________________________________________
Rails mailing list
Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
http://lists.rubyonrails.org/mailman/listinfo/rails