Подтвердить что ты не робот

Rails more_than model validation против атрибута модели

У меня есть модель Trip, которая среди других атрибутов имеет значение start_odometer и end_odometer. В моей модели я хотел бы подтвердить, что конечный одометр больше, чем исходный одометр. Конечный одометр также может быть пустым, потому что поездка может еще не закончиться.

Однако я не могу понять, как сравнить один атрибут с другим.

В trip.rb:

сравнивается с символом:

validates_numericality_of :end_odometer, :greater_than => :start_odometer, :allow_blank => true

дает мне ошибку:

АргументError в индексе TripsController #

: more_than должно быть числом

сравнивается с переменной:

validates_numericality_of :end_odometer, :greater_than => start_odometer, :allow_blank => true

NameError в индексе TripsController #

undefined локальная переменная или метод `start_odometer 'для #

4b9b3361

Ответ 1

Вам, вероятно, понадобится написать специальный метод проверки в вашей модели для этого...

validate :odometer_value_order

def odometer_value_order
  if self.end_odometer && (self.start_odometer > self.end_odometer)
    self.errors.add_to_base("End odometer value must be greater than start odometer value.")
  end
end

Ответ 2

Для этого случая необязательно нужен специальный метод проверки. На самом деле, это немного перебор, когда вы можете сделать это с одной строкой. Предложение jn80842 близко, но вы должны обернуть его в Proc или Lambda, чтобы он работал.

validates_numericality_of :end_odometer, :greater_than => Proc.new { |r| r.start_odometer }, :allow_blank => true

Ответ 3

Вы можете проверить атрибут модели, если используете Proc.

В rails4 вы сделали бы что-то вроде этого:

class Trip < ActiveRecord::Base
  validates_numericality_of :start_odometer, less_than: ->(trip) { trip.end_odometer }
  validates_numericality_of :end_odometer, greater_than: ->(trip) { trip.start_odometer }
end

Ответ 4

Это немного kludgy, но это, похоже, работает:

validates_numericality_of :end_odometer, :greater_than => :start_odometer.to_i, :allow_blank => true