问题
I have a datetime field in my ActiveRecord model (in Rails) and I need to protect my model from crashes when date fieid is out of ranges.
I found this question and and tried to make similarly:
class Something < ActiveRecord::Base
validate :important_date_is_valid_datetime, on: :create
validates :important_date, presence: true
private
def important_date_is_valid_datetime
if (DateTime.parse(important_date.to_s()) rescue ArgumentError) == ArgumentError then
errors.add(:important_date, 'must be a valid datetime')
end
end
end
This code can 'validate' datetime field but it don't abort field parsing if valie is out of range:
irb(main):007:0> Something.new(important_date: "2015-20-40").valid?
ArgumentError: argument out of range
from /home/shau-kote/.gem/ruby/2.1.0/gems/activesupport-4.2.0/lib/active_support/values/time_zone.rb:350:in `initialize'
from /home/shau-kote/.gem/ruby/2.1.0/gems/activesupport-4.2.0/lib/active_support/values/time_zone.rb:350:in `new'
from /home/shau-kote/.gem/ruby/2.1.0/gems/activesupport-4.2.0/lib/active_support/values/time_zone.rb:350:in `parse'
...
Can I prevent similar crashes?
回答1:
This is an issue with Rails 4 where the exception gets thrown before your validators are even called. There is a pull request that brings back the behavior of Rails 3 where a invalid date is just nil. This pull request seems to be merged, so maybe updating your Rails version can already fix the problem.
For the meantime I can think of two workarounds: First, you could use client side validations that of course can be tampered with if wanted but would protect users using your app in "good faith" and second, instead of using a validation you could be checking for a valid date (or the ArgumentError respectively) in the controller before the parameter is used to set the datetime attribute. Both options are not optimal but should prevent more crashes.
来源:https://stackoverflow.com/questions/27789968/activerecord-abort-datetime-parsing-if-value-is-invalid