flexible_date

Make ActiveRecord understand any date format you want.

How to use

Within your model, you should do:

flexible_date :my_date_field

And in config/locales/br.yml (or your native language):

br:
  flexible_date:
    configuration:
      format: "%d/%m/%Y"
    messages:
      with_suffix:
        invalid: "inválida."
      without_suffix:
        invalid: "inválida."

Or, in a reduced form, when messages for with or without suffix are the same:

br:
  flexible_date:
    configuration:
      format: "%d/%m/%Y"
    messages:
      invalid: "inválida."

Date format follows the same pattern used by strptime and strftime. This will generate a my_date_field_flex “property” in which you can enter the date as string in the specified format and then the correct date will be stored in my_date_field.

When an error occurs, the “with_suffix” messages are generated for the “flex” fields and “without_suffix” messages are generated for the regular ones.

Talk is cheap, let’s see the code (given any of the locale files above):

class Event < ActiveRecord::Base
  flexible_date :start_date, :end_date
end

event = Event.new
event.start_date_flex = "31/01/2011"
event.end_date_flex =  "28/02/2011"
event.start_date.should == Date.new(2011, 01, 31)
event.end_date.should == Date.new(2011, 02, 28)

And values assigned to regular fields are returned by _flex fields in the specified format:

event = Event.new :start_date => '2011-01-31',
                  :end_date => Date.new(2011, 02, 28)
event.start_date_flex.should == "31/01/2011"
event.end_date_flex.should == "28/02/2011"

Suffix can be customized:

class Event < ActiveRecord::Base
  flexible_date :judgement_day, :suffix => 'yyz'
end

event = Event.new
event.judgement_day_yyz = "28/02/2011"
event.judgement_day.should == Date.new(2011, 02, 28)

flexible_date supports conditional execution through the :if option. The object itself is passed as parameter to the block:

class Event < ActiveRecord::Base
  flexible_date :payday, :if => Proc.new { |n| n.description.blank? }
end

event = Event.new(:description => "some content")
event.payday_flex = "20/05/2011"
event.should_not be_valid

How to install

For Rails 3.1, just run:

gem install flexible_date

For Rails 3.0:

gem install flexible_date -v=0.3.0

Do you know a better/standard solution?

My intention is to allow users typing dates directly to text fields in their own local format. I didn’t find a solution for this problem in Rails itself. If you have a better solution, please let me know.

No, default select fields, separated by day, month and year are not a solution.

Copyright © 2011 Rodrigo Manhães. See LICENSE.txt for further details.