【发布时间】:2010-11-25 03:35:30
【问题描述】:
rails 是否对日期时间进行任何验证?我找到了一个插件 http://github.com/adzap/validates_timeliness/tree/master, 但它似乎应该开箱即用。
【问题讨论】:
-
我爱
validates_timeliness。它可以作为 gem 安装。安装速度与复制粘贴所选答案的速度差不多。
rails 是否对日期时间进行任何验证?我找到了一个插件 http://github.com/adzap/validates_timeliness/tree/master, 但它似乎应该开箱即用。
【问题讨论】:
validates_timeliness。它可以作为 gem 安装。安装速度与复制粘贴所选答案的速度差不多。
DateTimes 没有内置的 ActiveRecord 验证器,但您可以轻松地将这种功能添加到 ActiveRecord 模型中,而无需使用插件,如下所示:
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
【讨论】:
validates_timeliness,但在使用 getter 和 setter 时遇到了问题。这非常有效。
DateTime.parse(happened_at) rescue errors.add(:happened_at, 'must be a valid datetime')?拯救 ArgumentError 只是为了检查它是否是 ArgumentError 对我来说没有多大意义。
no implicit conversion of ActiveSupport::TimeWithZone into String,试试to_sDateTime.parse(happened_at.to_s)
Gabe 的回答对我没有用,所以这是我为验证我的日期所做的:
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
我只是想验证日期实际上是一个日期,而不是字符串、字符、int、float 等......
更复杂的日期验证可以在这里找到:https://github.com/codegram/date_validator
【讨论】:
Rails 的最新版本将在验证之前将 type cast 值,因此无效值将作为 nils 传递给自定义验证器。我正在做这样的事情:
# 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
【讨论】:
您可以自己创建自定义日期时间验证器
1) 在 app 目录中创建一个名为 validators 的文件夹
2) 创建一个文件 datetime_validator.rb。在 app/validators 目录中包含以下内容
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) 将此验证应用于模型
class YourModel < ActiveRecord::Base
validates :happend_at, datetime: true
end
4) 在 application.rb 中添加以下行
config.autoload_paths += %W["#{config.root}/app/validators/"]
5) 重新启动您的 Rails 应用程序
注意:上述方法在rails 4中测试过
【讨论】:
DateTimeValidator(大写T)因为它是DateTime你正在验证。从constantize 的角度来看更有意义。
我推荐一颗宝石date_validator。见https://rubygems.org/gems/date_validator。它维护良好,API 简单紧凑。
【讨论】:
验证日期是非常必要的。使用默认的 Rails 表单助手,您可以选择像 9 月 31 日这样的日期。
【讨论】: