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
How to validate the date such that it is after today in Rails?
提问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) }

