ActiveRecord:如果值无效,则中止datetime解析

我的ActiveRecord模型中有一个datetime字段(在Rails中),当date fieid超出范围时,我需要保护我的模型免于崩溃。

我发现了这个问题,并尝试做同样的事情 :

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 

此代码可以“validation”datetime字段,但如果valie超出范围,则不会中止字段解析:

 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' ... 

我可以防止类似的崩溃吗?

这是Rails 4的一个问题,即在调用validation程序之前抛出exception。 有一个pull请求可以恢复Rails 3的行为,其中无效日期只有nil。 这个拉取请求似乎已合并,因此更新您的Rails版本已经可以解决问题。

与此同时,我可以想到两个解决方法:首先,您可以使用客户端validation,如果需要,当然可以篡改,但会保护用户“善意”使用您的应用程序,其次,而不是使用validation您可能是在使用参数设置datetime属性之前,在控制器中检查有效日期(或ArgumentError)。 这两个选项都不是最佳选择,但应防止更多崩溃。