Does rails do any validation for datetime? I found a plugin http://github.com/adzap/validates_timeliness/tree/master, but it seems like something that should come in out
It's quite necessary to validate dates. With the default Rails form helpers you could select dates like September 31st.
You can create a custom datetime validator by yourself
1) create a folder called validators in inside app directory
2) create a file datetime_validator.rb. with the following content inside app/validators directory
class DatetimeValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
if ((DateTime.parse(value) rescue ArgumentError) == ArgumentError)
record.errors[attribute] << (options[:message] || "must be a valid datetime")
end
end
end
3) Apply this validation on model
class YourModel < ActiveRecord::Base
validates :happend_at, datetime: true
end
4) Add the below line in application.rb
config.autoload_paths += %W["#{config.root}/app/validators/"]
5) Restart your rails application
Note: The above method tested in rails 4
Recent versions of Rails will type cast values before validation, so invalid values will be passed as nil
s to custom validators. I'm doing something like this:
# app/validators/date_time_validator.rb
class DateTimeValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
if record.public_send("#{attribute}_before_type_cast").present? && value.blank?
record.errors.add(attribute, :invalid)
end
end
end
# app/models/something.rb
class Something < ActiveRecord::Base
validates :sold_at, date_time: true
end
# spec/models/something_spec.rb (using factory_girl and RSpec)
describe Something do
subject { build(:something) }
it 'should validate that :sold_at is datetimey' do
is_expected.not_to allow_value(0, '0', 'lorem').for(:sold_at).with_message(:invalid)
is_expected.to allow_value(Time.current.iso8601).for(:sold_at)
end
end
There's no built-in ActiveRecord validator for DateTimes, but you can easily add this sort of capability to an ActiveRecord model, without using a plugin, with something like this:
class Thing < ActiveRecord::Base
validate :happened_at_is_valid_datetime
def happened_at_is_valid_datetime
errors.add(:happened_at, 'must be a valid datetime') if ((DateTime.parse(happened_at) rescue ArgumentError) == ArgumentError)
end
end
Gabe's answer didn't work for me, so here's what I did to validate my dates:
class MyModel < ActiveRecord::Base
validate :mydate_is_date?
private
def mydate_is_date?
if !mydate.is_a?(Date)
errors.add(:mydate, 'must be a valid date')
end
end
end
I was just looking to validate that the date is in fact a date, and not a string, character, int, float, etc...
More complex date validation can be found here: https://github.com/codegram/date_validator
I recommend a gem date_validator
. See https://rubygems.org/gems/date_validator. It is well maintained and its API is simple and compact.