Date validation

64 views
Skip to first unread message

dklopp

unread,
Sep 7, 2011, 4:46:22 PM9/7/11
to Hobo Users
Hi. I got a hobo 1.0.1 project using the validates_timeliness gem in
rails 2.3.8.
I was really surprised that "validates_date :some_date" didn't work
with invalid dates (like 31 Feb), and then i read this

http://groups.google.com/group/hobousers/browse_thread/thread/a55e4ac3176dff86/21490e6603529797?lnk=gst&q=date+validation#21490e6603529797

So my question is, how do I validate a date in hobo 1.0.1? (preferably
without javascript)

Thx

kevinpfromnm

unread,
Sep 7, 2011, 5:19:28 PM9/7/11
to hobo...@googlegroups.com
that thread has a way in there (sort of).  basically add a custom validation and make a date object from the appropriate field.  rescue the exception and have that throw a validation error.  not sure if the continued validation will throw the error before returning though.

dklopp

unread,
Sep 7, 2011, 7:08:31 PM9/7/11
to hobo...@googlegroups.com
If I understand you correctly, you are suggesting something like this:

---------------------------------
fields do
####
    fecha_solicitud :date, :required
    timestamps
end

validate :my_date

def my_date
    begin
      date_parsed = fecha_solicitud.to_date
    rescue
      errors.add(:fecha_solicitud, "Invalid date")
    end
end
-----------------------

Unfortunately that brings

ArgumentError (invalid date):
/opt/ruby1.8/lib/ruby/1.8/date.rb:752:in `new'
hobo (1.0.1) lib/hobo/model.rb:463:in `convert_type_for_mass_assignment'
hobo (1.0.1) lib/hobo/model.rb:398:in `attributes='
hobosupport (1.0.1) lib/hobo_support/hash.rb:12:in `map_hash'
hobosupport (1.0.1) lib/hobo_support/hash.rb:12:in `each'
hobosupport (1.0.1) lib/hobo_support/hash.rb:12:in `map_hash'
hobo (1.0.1) lib/hobo/model.rb:398:in `attributes='
hobo (1.0.1) lib/hobo/permissions.rb:50:in `new'
hobo (1.0.1) lib/hobo/permissions.rb:50:in `user_new'
hobo (1.0.1) lib/hobo/model_controller.rb:552:in `new_for_create'
hobo (1.0.1) lib/hobo/model_controller.rb:523:in `hobo_create'
app/controllers/solicitud_internets_controller.rb:17:in `create'
hobo (1.0.1) lib/hobo/controller.rb:23:in `call'
hobo (1.0.1) lib/hobo/controller.rb:23:in `included_in_class'
/opt/ruby1.8/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/opt/ruby1.8/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/opt/ruby1.8/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/opt/ruby1.8/lib/ruby/1.8/webrick/server.rb:162:in `start'
/opt/ruby1.8/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/opt/ruby1.8/lib/ruby/1.8/webrick/server.rb:95:in `start'
/opt/ruby1.8/lib/ruby/1.8/webrick/server.rb:92:in `each'
/opt/ruby1.8/lib/ruby/1.8/webrick/server.rb:92:in `start'
/opt/ruby1.8/lib/ruby/1.8/webrick/server.rb:23:in `start'
/opt/ruby1.8/lib/ruby/1.8/webrick/server.rb:82:in `start'

I'm missing something?

kevinpfromnm

unread,
Sep 8, 2011, 11:56:00 AM9/8/11
to hobo...@googlegroups.com
No, that's what I was worried that the normal assignment would cause the error despite that.  You might be able to get around it by redefining the assignment operator though at this point it's getting awfully hackish.

def date_field_name=(value)
  write_attribute(:date_field_name, turn value into a Date object here)
end

or redefine convert_type_for_mass_assignment in the model to handle invalid dates.  or add a custom bit in the controller to change the parameter before continuing to hobo_create.  Ugly any way you wrap it really.
 

Matt Jones

unread,
Sep 8, 2011, 6:51:41 PM9/8/11
to hobo...@googlegroups.com

Are you 100% certain about that "without JS" part? Because the "use a datepicker" solution is really much easier than any of the alternatives.

In any case, here's a summary of the issues:

- the assignment blows up well before any validations can actually take effect; it's happening in the code that assigns attributes from a hash.

- even if the assignment could be made to work (Kevin's solution should), the dropdowns won't automatically re-populate when an invalid date is entered: they extract the values to use from the actual object

Validates_timeliness isn't able to help out here because (for reasons lost to history) Hobo doesn't use the standard multiparameter assignment stuff in ActiveRecord. You can tell because it creates fields named some_model[some_date_field][year], etc rather than some_model[some_date_field][1i]. Thus, the methods that validates_timeliness hooks into never get called.

Another alternative method of date-entry I've used in a few apps was to switch to a plain text field. To set this up, add this to an initializer:

HoboFields.field_types[:text_date] = Date
HoboFields::PLAIN_TYPES[:text_date] = Date
class Date
COLUMN_TYPE = :date
end

and this in your taglibs:

<def tag="input" for="text_date" attrs="name, no-wrapper">
<%= text_field_tag(name, this.to_s, attributes) %>
<do unless="&no_wrapper"><label>MM / DD / YYYY</label></do>
</def>

This does solve the "blows up on invalid dates" problem, but instead leaves you with the standard Rails behavior if an invalid string is assigned to a date field: the string is ignored and the field is set to nil. In this case, I *think* validates_timeliness might actually be able to help - not sure, though.

--Matt Jones

dklopp

unread,
Sep 9, 2011, 5:06:24 PM9/9/11
to hobo...@googlegroups.com
Not 100% sure, actually I'm trying to do it with the JQuery plugin now (nice plugin!) but I have a problem saving the dates to the db. Don't think this is a hobo issue, but we are already talking about it.

I have this in ../config/initializers/date_formats.rb

Time::DATE_FORMATS[:default] = "%d/%m/%Y %I:%M%p"
Date::DATE_FORMATS[:default] = "%d/%m/%Y"

and this in application.dryml

<include src="hobo-jquery" plugin="hobo-jquery" />

<extend tag="page">
    <old-page merge>
      <custom-scripts:>
        <hjq-assets/>
      </custom-scripts>
    </old-page>
</extend>

<def tag="input" for="Date">
    <hjq-datepicker dateFormat="dd/mm/yy" merge />
</def>

All the inputs for dates show the expected dd/mm/yyyy format, but when i try to save the new value it swap the day and month. (I see this when I'm saving 12/09/2011 and after the save I see this in the db 09/12/2011) Of course when I save 13/09/2011 It saves a nil value.

Any ideas?

dklopp

unread,
Sep 13, 2011, 3:14:41 PM9/13/11
to hobo...@googlegroups.com
Well, to fix the behavior of my previous post you will need this: http://blog.nominet.org.uk/tech/2007/06/14/date-and-time-formating-issues-in-ruby-on-rails/. That seems to do the trick! 

Thanks
Reply all
Reply to author
Forward
0 new messages