如何在今天的Rails中验证日期?

时间:2011-12-14 22:34:57

标签: ruby-on-rails ruby validation

我有一个Active Record模型,其中包含属性:expiry_date。我如何进行验证,使其在今天(当时的当前日期)之后?我对Rails和ruby完全不熟悉,我找不到类似的问题来回答这个问题吗?

我正在使用Rails 3.1.3和ruby 1.8.7

5 个答案:

答案 0 :(得分:63)

您的问题(几乎)完全回答in the Rails guides

这是他们给出的示例代码。此类验证日期是在过去,而您的问题是如何验证日期是否在 future ,但是调整它应该非常简单:

class Invoice < ActiveRecord::Base
  validate :expiration_date_cannot_be_in_the_past

  def expiration_date_cannot_be_in_the_past
    if expiration_date.present? && expiration_date < Date.today
      errors.add(:expiration_date, "can't be in the past")
    end
  end    
end

答案 1 :(得分:18)

以下是设置自定义验证器的代码:

#app/validators/not_in_past_validator.rb
class NotInPastValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    if value.blank?
      record.errors.add attribute, (options[:message] || "can't be blank")
    elsif value <= Time.zone.today
      record.errors.add attribute,
                        (options[:message] || "can't be in the past")
    end
  end
end

在你的模特中:

validates :signed_date, not_in_past: true

答案 2 :(得分:3)

我接受了@dankohn的回答,并更新为I18n准备好了。我还删除了blank测试,因为这不是此验证程序的责任,可以通过将presence: true添加到验证调用来轻松启用。

更新的类,现在命名为in_future,我认为它比not_in_past更好

class InFutureValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    record.errors.add(attribute, (options[:message] || :in_future)) unless in_future?(value)
  end

  def in_future?(date)
    date.present? && date > Time.zone.today
  end
end

现在将in_future密钥添加到您的本地化文件中。

对于errors.messages.in_future下的所有字段,例如对于荷兰人:

nl:
  errors:
    messages:
      in_future: 'moet in de toekomst zijn'

activerecord.errors.models.MODEL.attributes.FIELD.in_future下的每个字段,例如对于荷兰语end_date模型中的Vacancy

nl:
  activerecord:
    errors:
      models:
        vacancy:
          attributes:
            end_date:
              in_future: 'moet in de toekomst zijn'

答案 3 :(得分:3)

在Rails 4+中,有future?个对象的past?DateTime方法,因此更简单的答案是

class Invoice < ActiveRecord::Base
  validate :expiration_date_cannot_be_in_the_past

  def expiration_date_cannot_be_in_the_past
    if expiration_date.present? && expiration_date.past?
      errors.add(:expiration_date, "can't be in the past")
    end
  end    
end

答案 4 :(得分:2)

最简单且最有效的解决方案是使用Rails的内置验证。只需验证它:

validates :expiry_date, inclusion: { in: (Date.today..Date.today+5.years) }