Rails Date Validation - Step by Step

Update 5/31/2008: Use ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS

I have invested some time to get Rails date validation to work (whoo hoo!).

Without further ado, here are the step by step instructions:
1. Download Rails Date Kit from my site. Note that I got the original kit from http://www.methods.co.nz/rails_date_kit/rails_date_kit.html.
Extract the files in rails_date_kit_1.2.0.tar.gz to <your application>/vendor/plugins/rails_date_kit.
Rails Date Kit

2. Get the Validates Date Time plugin by running the following command in your application directory:

script/plugin install http://svn.viney.net.nz/things/rails/plugins/validates_date_time

You should have a new directory in your <your application>/vendor/plugins/validates_date_time
Validates Date Time-1

3. Put the necessary files in the right places.

Copy vendor/plugins/rails_date_kit/calendar.js to public/javascripts
Copy vendor/plugins/rails_date_kit/calendar.css to public/stylesheets
Copy vendor/plugins/rails_date_kit/calendar_prev.png to public/images
Copy vendor/plugins/rails_date_kit/calendar_next.png to public/images
Copy vendor/plugins/rails_date_kit/date_helper.rb to app/helpers


4. Include the css and javascript files for the calendar in your page header (e.g. view/layout/tasks.html.erb):

<%= stylesheet_link_tag ‘calendar.css’ %>
<%= javascript_include_tag ‘calendar’ %>

My application uses application.rhtml, thus I just added the lines there.

5. Create a new file called date_formats.rb in config/initializers. All you need to add is:

ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS.merge!(:default_date => ‘%m/%d/%Y’)

Note the capital Y in ‘%m/%d/%Y’. Obviously, you can add more date formats as needed.
Update: Adjust the date format accordingly to your locale. For example, use ‘%d/%m/%Y’ for displaying date/month/year.

6. Use the following code to add the date field in your input form (e.g. view/tasks/new.html.erb):

<%= date_field :task, :due_date, :format => ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS[:default_date], :value => @task.due_date %>

You can also wrap the whole ‘ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS[:default_date]‘ into a function in app/helpers/application_helper.rb.

6. Tell your model to use en-us date format by adding the following line:

ValidatesDateTime.us_date_format = true #use mm/dd/yyyy format

Update: Set ValidatesDateTime.us_date_format to ‘false’ if your date format is not month/date/year.

7. Validate away! :) Here’s an example of my model validation:

Class Task < ActiveRecord::Base
.
.
validates_date :due_date, :allow_nil => true
.
.
End


Enjoy! :)
Post any questions in the comment.

8 Responses to “Rails Date Validation - Step by Step”

  1. John McAuley Says:

    Hi Handy,

    Thanks for the great tutorial. It is really very usefull, however I am getting one error on your implementation. Whne I place ValidatesDateTime.us_date_format = true #use mm/dd/yyyy format in my model I receive the following error:

    uninitialized constant Visit::ValidatesDateTime

    Have you any ideas, I’m pulling out my hair!

    Thanks again.

    j

  2. John McAuley Says:

    Hi Handy,

    I installed the plugin as a above, instead of downloading it, and the error has disappeared but there are only nulls being writted to the database. Any ideas?

    j

  3. John McAuley Says:

    Handy,

    I got all nulls untill I did the following:

    ValidatesDateTime.us_date_format = false #use mm/dd/yyyy format

    Hey Presto, it worked.

    Laters,
    j

  4. Handy Says:

    John,

    This post is used mainly for en-us locale. If you use a different locale, you’re correct that ValidatesDateTime.us_date_format = false.

    Also, don’t forget to change step 5:
    ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS.merge!(:default_date => ‘%m/%d/%Y’)

    The default date format for display should be changed as well.

    Let me know if you have other question.

    Handy

  5. Cheri A Says:

    Ok, the ruby code did not go through on my previous post.
    I want to embed the calendar in a Rails form using
    “form_for @posting do |f|”?

    Thanks,
    Cheri

  6. Handy Says:

    Cheri,

    Interesting idea… I’ve never thought about doing the embedded calendar since I think the form looks more clean for my project. Different projects have different requirements, correct? :)

    The date field is calling calendar_open from public/javascripts/calendar.js.
    To show the calendar, you may try to call calendar_open with the same parameters on a hidden date field. When the user clicks on the date, the calendar should update the hidden field, which can be submitted when the user accepts the form.

    Let me know if this works and I’ll be happy to put a link to your investigation.

    Handy

  7. Colin Stevens Says:

    Hi Handy,

    One problem i’ve come across is that it seems impossible to change a date to nil from a valid date once it is set - any ideas ?

  8. Handy Says:

    Colin,

    I can still delete a valid date from my form.

    A couple things to check:
    - The field value should be empty when the user saves the form. Can you verify that the controller correctly get an empty string from the field?
    - Are you sure the date is not protected field?

    Handy

Leave a Reply