Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I validate a date in rails?

I want to validate a date in my model in Ruby on Rails, however, the day, month and year values are already converted into an incorrect date by the time they reach my model.

For example, if I enter February 31st 2009 in my view, when I use Model.new(params[:model]) in my controller, it converts it to "March 3rd 2009", which my model then sees as a valid date, which it is, but it is incorrect.

I would like to be able to do this validation in my model. Is there any way that I can, or am I going about this completely wrong?

I found this "Date validation" that discusses the problem but it never was resolved.

like image 306
Megamug Avatar asked Feb 28 '09 01:02

Megamug


1 Answers

I'm guessing you're using the date_select helper to generate the tags for the date. Another way you could do it is to use select form helper for the day, month, year fields. Like this (example I used is the created_at date field):

<%= f.select :month, (1..12).to_a, selected: @user.created_at.month %> <%= f.select :day, (1..31).to_a, selected: @user.created_at.day %> <%= f.select :year, ((Time.now.year - 20)..Time.now.year).to_a, selected: @user.created_at.year %> 

And in the model, you validate the date:

attr_accessor :month, :day, :year validate :validate_created_at  private  def convert_created_at   begin     self.created_at = Date.civil(self.year.to_i, self.month.to_i, self.day.to_i)   rescue ArgumentError     false   end end  def validate_created_at   errors.add("Created at date", "is invalid.") unless convert_created_at end 

If you're looking for a plugin solution, I'd checkout the validates_timeliness plugin. It works like this (from the github page):

class Person < ActiveRecord::Base   validates_date :date_of_birth, on_or_before: lambda { Date.current }   # or   validates :date_of_birth, timeliness: { on_or_before: lambda { Date.current }, type: :date } end  

The list of validation methods available are as follows:

validates_date     - validate value as date validates_time     - validate value as time only i.e. '12:20pm' validates_datetime - validate value as a full date and time validates          - use the :timeliness key and set the type in the hash. 
like image 50
Jack Chu Avatar answered Oct 05 '22 20:10

Jack Chu