在日期时间验证中构建的rails

Dan*_*iel 31 validation ruby-on-rails

rails是否对datetime进行了任何验证?我找到了一个插件 http://github.com/adzap/validates_timeliness/tree/master,但它似乎应该是开箱即用的东西.

Gab*_*mbe 41

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
Run Code Online (Sandbox Code Playgroud)

  • 为什么不:`DateTime.parse(happen_at)rescue errors.add(:happen_at,'必须是一个有效的日期时间')`?拯救ArgumentError只是为了检查它是否是一个ArgumentError对我来说没什么意义. (7认同)
  • 根据数据库的列,通常不会进行类型转换吗?这不是不必要的吗? (2认同)

Sau*_*oss 13

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
Run Code Online (Sandbox Code Playgroud)

我只是想验证日期实际上是一个日期,而不是字符串,字符,int,float等...

可以在此处找到更复杂的日期验证:https://github.com/codegram/date_validator

  • @MichaelSchmitz - 值得编写代码,因为代码是自我解释的 - 看着代码的新人可能不知道那个宝石的存在,它为简单的任务增加了额外的开销. (2认同)

Hal*_*gür 9

最新版本的Rails将在验证之前键入强制转换值,因此无效值将作为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
Run Code Online (Sandbox Code Playgroud)
# app/models/something.rb
class Something < ActiveRecord::Base
  validates :sold_at, date_time: true
end
Run Code Online (Sandbox Code Playgroud)
# 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
Run Code Online (Sandbox Code Playgroud)


Ram*_*jan 5

您可以自己创建自定义日期时间验证器

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
Run Code Online (Sandbox Code Playgroud)

3)将此验证应用于模型

class YourModel < ActiveRecord::Base
  validates :happend_at, datetime: true
end
Run Code Online (Sandbox Code Playgroud)

4) 在 application.rb 中添加以下行

config.autoload_paths += %W["#{config.root}/app/validators/"]
Run Code Online (Sandbox Code Playgroud)

5) 重启你的 rails 应用程序

注意:以上方法在rails 4中测试