可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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 #
回答1:
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
回答2:
You don't necessarily need a custom validation method for this case. In fact, it's a bit overkill when you can do it with one line. jn80842's suggestion is close, but you must wrap it in a Proc or Lambda for it to work.
validates_numericality_of :end_odometer, :greater_than => Proc.new { |r| r.start_odometer }, :allow_blank => true
回答3:
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
回答4:
It's a bit kludgy, but this seems to work:
validates_numericality_of :end_odometer, :greater_than => :start_odometer.to_i, :allow_blank => true