Ruby-on-rails 如何在 Rails 中验证日期在今天之后?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8512691/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 02:29:43  来源:igfitidea点击:

How to validate the date such that it is after today in Rails?

ruby-on-railsrubyvalidation

提问by coding_pleasures

I have an Active Record model that contains attributes: expiry_date. How do I go about validating it such that it is after today(present date at that time)? I am totally new to Rails and ruby and I couldn't find a similar question answering exactly this?

我有一个包含属性的 Active Record 模型:expiry_date。我如何验证它是在今天之后(当时的当前日期)?我是 Rails 和 ruby​​ 的新手,我找不到类似的问题来回答这个问题?

I am using Rails 3.1.3 and ruby 1.8.7

我正在使用 Rails 3.1.3 和 ruby​​ 1.8.7

回答by apneadiving

Your question is (almost) exactly answered in the Rails guides.

您的问题(几乎)在 Rails 指南中得到了准确回答。

Here's the example code they give. This class validates that the date is in the past, while your question is how to validate that the date is in the future, but adapting it should be pretty easy:

这是他们提供的示例代码。这个类验证日期是过去的,而您的问题是如何验证日期是未来的,但调整它应该很容易:

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

回答by Dan Kohn

Here's the code to set up a custom validator:

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

#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

And in your model:

在你的模型中:

validates :signed_date, not_in_past: true

回答by Koen.

I took @dankohn answer, and updated to be I18n ready. I also removed the blanktest, because that's not the responsibility of this validator, and can easily be enabled by adding presence: trueto the validates call.

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

The updated class, now named in_future, which I think is nicer than not_in_past

更新的类,现在命名为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

Now add the in_futurekey to your localization file.

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

For all fields under errors.messages.in_future, e.g. for Dutch:

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

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

Or per field under activerecord.errors.models.MODEL.attributes.FIELD.in_future, e.g. for the end_datein a Vacancymodel in Dutch:

或每场下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'

回答by Obromios

In rails 4+ there are future?and past?methods for DateTimeobjects, so a simpler answer is

在轨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

回答by Amit Attri

The simplest and working solution is to use the in-built validation from Rails. Just validates it like that:

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

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