views:

29

answers:

1

I'm trying to get a text field that my users can enter in something that is parsable by the Chronic gem. Here is my model file:

require 'chronic'

class Event < ActiveRecord::Base
  belongs_to :user

  validates_presence_of :e_time
  before_validation :parse_date

  def parse_date
    self.e_time = Chronic.parse(self.e_time_before_type_cast) if self.e_time_before_type_cast
  end
end

I think that it is being called because if I misspell something in parse_date, it complains that it doesn't exist. I've also tried before_save :parse_date, but that doesn't work either.

How could I get this to work?

Thanks

+1  A: 

This kind of situation looks like a good candidate for using virtual attributes in your Event model to represent the natural language dates and times for the view's purpose while the real attribute is backed to the database. The general technique is described in this screencast

So you might have in your model:

class Event < ActiveRecord::Base
  validates_presence_of :e_time

  def chronic_e_time
    self.e_time // Or whatever way you want to represent this
  end

  def chronic_e_time=(s)
    self.e_time = Chronic.parse(s) if s
  end
end

And in your view:

<% form_for @event do |f| %>

  <% f.text_field :chronic_e_time %>

<% end %>

If the parse fails, then e_time will remain nil and your validation will stop the record being saved.

bjg
Thanks! This works beautifully.
Reti
One change I had to do: Change `self.e_time = Chronic.parse(s) if s` to `self.e_time = Chronic.parse(s.to_date) if s` The one you gave wouldn't parse real UTC datetimes so when I was editing the form, it never parse something like `2010-07-22 12:00:00 -0700` as the correct date (it would return nil) because of the `-700` for the time zone.
Reti