Метод проверки Rails, сравнивающий два поля?
Моя модель имеет два поля, которые я хочу сравнить друг с другом как часть проверки. Я хочу быть уверенным, что end_time после start_time. Я написал метод проверки, чтобы сравнить их, но я должен делать что-то неправильно, потому что значения всегда равны нулю. Может кто-нибудь помочь?
class LogEntry < ActiveRecord::Base
validates :start_time, :presence => { :message => "must be a valid date/time" }
validates :end_time, :presence => {:message => "must be a valid date/time"}
validate :start_must_be_before_end_time
def start_must_be_before_end_time
errors.add(:start_time, "must be before end time") unless
start_time > end_time
end
end
получает ошибку
undefined method `>' for nil:NilClass
Итак, start_time и/или end_time равны нулю. Я думал, что следую многим примерам, которые я нашел, но, видимо, нет. Что мне не хватает?
Спасибо.
Ответы
Ответ 1
Мое лучшее предположение: вам нужен ваш метод, чтобы он выглядел так:
private
def start_must_be_before_end_time
errors.add(:start_time, "must be before end time") unless
start_time < end_time
end
(Также обратите внимание на <
, а не на >
(или измените на if
и >=
)
Если это не сработает, вы также должны проверить, что start_time
и end_time
правильно определены в контроллере, поскольку могут произойти смешные вещи, если время создано более чем в одном элементе формы.
Ответ 2
Вам нужно проверить наличие на наличие (и пропустить шаг проверки, если он отсутствует).
def start_must_be_before_end_time
return unless start_time and end_time
errors.add(:start_time, "must be before end time") unless start_time < end_time
end
Печать "должна быть допустимой датой/временем" ИЛИ "время начала должно быть до окончания времени".
Альтернативный
def start_must_be_before_end_time
valid = start_time && end_time && start_time < end_time
errors.add(:start_time, "must be before end time") unless valid
end
Отпечатки "время начала должно быть допустимой датой/временем" И "время начала должно быть до конечного времени", если start_time или end_time не установлены.
Индивидуальное предпочтение сначала, так как оно показывает только то, что пользователь сделал неправильно. Последний подобен многим веб-сайтам, которые просто загружают 20 строк текста ошибки пользователю только потому, что программист подумал, что было бы неплохо увидеть каждый результат проверки. Плохой UX.
Ответ 3
Очистить и очистить (и под управлением?)
Я считаю это самым ясным для чтения:
В вашей модели
# ...
validates_presence_of :start_time, :end_time
validate :end_time_is_after_start_time
# ...
#######
private
#######
def end_time_is_after_start_time
return if end_time.blank? || start_time.blank?
if end_time < start_time
errors.add(:end_time, "cannot be before the start time")
end
end
Ответ 4
Вы можете использовать validates_timeliness gem https://github.com/adzap/validates_timeliness
Ответ 5
start_time.to_i < end_time.to_i
должен исправить это. Вы пытаетесь сравнить datetime, но по какой-то причине он не может, поэтому перед их сравнением преобразуйте их в int.