2009-12-31 6 views
18

J'ai un modèle Trip qui, entre autres attributs, a une valeur start_odometer et end_odometer. Dans mon modèle, je voudrais valider que l'odomètre final est plus grand que l'odomètre de départ. L'odomètre final peut également être vide car le trajet n'est peut-être pas encore terminé.Rails greater_than validation du modèle par rapport à l'attribut du modèle

Cependant, je n'arrive pas à comprendre comment comparer un attribut à un autre.

En trip.rb:

comparer contre le symbole:

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

me donne l'erreur:

ArgumentError in TripsController#index

:greater_than must be a number

comparant à la 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

Je pense que ce serait quelque chose d'utile dans Rails. Peut-être soumettre un billet au phare: http://rails.lighthouseapp.com pour cela? –

Répondre

18

Vous aurez probablement besoin d'écrire une méthode de validation personnalisée dans votre modèle pour cette ...

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 
+0

Merci, ça marche super! – Ryan

-4

Il est un peu kludgy, mais cela semble fonctionner:

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

Vous aurez besoin d'un proc ou lambda pour que cet exemple fonctionne. – holden

+3

Cela ne fonctionne certainement pas, ce qui convertit le symbole ': start_odometer' en un entier et le passe à': greater_than'. ** N'utilisez pas ce code, c'est complètement faux **. – meagar

32

Vous n » t nécessairement besoin d'une méthode de validation personnalisée pour ce cas. En fait, c'est un peu exagéré quand vous pouvez le faire avec une ligne. La suggestion de jn80842 est proche, mais vous devez l'emballer dans un Proc ou Lambda pour que cela fonctionne.

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

Cherchait la même chose et cette approche fonctionne très bien pour moi. – Sg1team

+4

Pas besoin non plus de 'Proc', juste': start_odometer' fonctionnera. –

6

Vous pouvez valider contre un attribut de modèle si vous utilisez un Proc.

En rails4 vous feriez quelque chose comme ceci:

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 
Questions connexes