Как проверить дату, такую, как после Rails?
У меня есть модель Active Record, которая содержит атрибуты: expiry_date. Как я могу проверить его таким образом, чтобы это было после сегодняшнего дня (текущая дата в то время)? Я совершенно не знаком с Rails и ruby, и я не мог найти аналогичный вопрос, отвечающий именно этому?
Я использую Rails 3.1.3 и ruby 1.8.7
Ответы
Ответ 1
Ваш вопрос (почти) точно ответил в направляющих Rails.
Вот пример кода, который они дают. Этот класс подтверждает, что дата в прошлом, в то время как ваш вопрос заключается в том, как подтвердить, что дата в будущем, но приспосабливать ее должно быть довольно легко:
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
Ответ 2
Вот код для настройки пользовательского валидатора:
#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
Ответ 3
Я взял @dankohn ответ и обновился, чтобы быть готовым. Я также удалил тест 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'
Ответ 4
Простейшим и рабочим решением является использование встроенной проверки Rails. Просто проверяет это так:
validates :expiry_date, inclusion: { in: (Date.today..Date.today+5.years) }