How to check the date in rails?

I want to confirm the date in my model in Ruby on Rails, however the values ​​of the day, month and year are already converted to the wrong date by the time they reach my model.

For example, if I enter February 31, 2009 in my opinion, when I use Model.new(params[:model]) in my controller, it will convert it to March 3, 2009, which my model then sees as a valid date, but this is not true.

I would like to be able to perform this check in my model. Is there a way I can, or am I completely wrong about this?

I found this " Date Check " discussing the issue, but it was never resolved.

+82
date ruby validation ruby-on-rails
Feb 28 '09 at 1:42
source share
9 answers

I assume that you are using the date_select to create tags for the date. Another way you could do this is to use the form form helper for the day, month, year fields. Like this (for example, I used the date_at created 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 confirm 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 are looking for a plugin solution, I would check out 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 

List of available verification methods:

 validates_date - validate value as date validates_time - validate value as time only ie '12:20pm' validates_datetime - validate value as a full date and time validates - use the :timeliness key and set the type in the hash. 
+54
Feb 28 '09 at 9:14
source share

Use of chronic gemstone:

 class MyModel < ActiveRecord::Base validate :valid_date? def valid_date? unless Chronic.parse(from_date) errors.add(:from_date, "is missing or invalid") end end end 
+19
Mar 11
source share

If you want compatibility with Rails 3 or Ruby 1.9, try the date_validator gem.

+17
Aug 24 '10 at 9:35 a.m.
source share

The active record provides _before_type_cast attributes, which contain the attribute source data before type casting. This can be useful for returning error messages with predefined values ​​or just for checking, which are not possible after type casting.

I would shy away from Daniel Von Fange's suggestion of redefining an accessory, because doing the check on the accessory slightly changed the access contract. In this situation, the active record has a function explicitly. Use it.

+9
Feb 09 2018-11-11T00:
source share

Since you need to process the date string before it is converted to a date in your model, I would redefine the accessory for this field

Say your published_date date field. Add this to the model object:

 def published_date=(value) # do sanity checking here # then hand it back to rails to convert and store self.write_attribute(:published_date, value) end 
+2
Feb 28 '09 at 2:10
source share

This is not a chronic answer.

 class Pimping < ActiveRecord::Base validate :valid_date? def valid_date? if scheduled_on.present? unless scheduled_on.is_a?(Time) errors.add(:scheduled_on, "Is an invalid date.") end end end 
+1
Apr 03 '13 at 18:41
source share

You can check the date and time (for example, somewhere in your controller with access to your parameters, if you use custom selections) ...

 # Set parameters year = params[:date][:year].to_i month = params[:date][:month].to_i mday = params[:date][:mday].to_i hour = params[:date][:hour].to_i minute = params[:date][:minute].to_i # Validate date, time and hour valid_date = Date.valid_date? year, month, mday valid_hour = (0..23).to_a.include? hour valid_minute = (0..59).to_a.include? minute valid_time = valid_hour && valid_minute # Check if parameters are valid and generate appropriate date if valid_date && valid_time second = 0 offset = '0' DateTime.civil(year, month, mday, hour, minute, second, offset) else # Some fallback if you want like ... DateTime.current.utc end 
0
Apr 28 '15 at 23:56
source share

A little later, but thanks How to check the date in rails? "I managed to write this validator, I hope someone is useful:

Inside model.rb

 validate :date_field_must_be_a_date_or_blank # If your field is called :date_field, use :date_field_before_type_cast def date_field_must_be_a_date_or_blank date_field_before_type_cast.to_date rescue ArgumentError errors.add(:birthday, :invalid) end 
0
Nov 30 '16 at 1:09
source share

Have you tried the validates_date_time plugin?

-3
Feb 28 '09 at 3:30
source share



All Articles