Метод проверки 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

Ответ 5

start_time.to_i < end_time.to_i должен исправить это. Вы пытаетесь сравнить datetime, но по какой-то причине он не может, поэтому перед их сравнением преобразуйте их в int.