Rails greater_than model validation against model attribute

Viewed 13515

I've got a Trip model, which among other attributes has a start_odometer and end_odometer value. In my model, i'd like to validate that the end odometer is larger than the starting odometer. The end odometer can also be blank because the trip may not have finished yet.

However, I can't figure out how to compare one attribute to another.

In trip.rb:

comparing against the symbol:

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

gives me the error:

ArgumentError in TripsController#index

:greater_than must be a number

comparing against the variable:

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

NameError in TripsController#index

undefined local variable or method `start_odometer' for #

4 Answers

You'll probably need to write a custom validation method in your model for this...

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

You can validate against a model attribute if you use a Proc.

In rails4 you would do something like this:

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

It's a bit kludgy, but this seems to work:

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