2009-12-22 18 views
21

primo luogo, vorrei dire che sono estremamente nuovo a Rails (giocato con esso una volta o due, ma mi costringe a scrivere un progetto completo con esso ora, ha iniziato su di esso ieri).convalida di un immobile modello è maggiore di un altro

Ora sto provando a convalidare che una proprietà del modello (terminologia?) È maggiore di un'altra. Questa sembrava essere un'istanza perfetta per validates_numericality_of con l'opzione greater_than, ma ahimè che genera un errore che mi dice greater_than expects a number, not a symbol. Se provo a digitare quel simbolo .to_f, ottengo un errore undefined method.

Ecco cosa ho fatto alla fine e sono curioso di sapere se esiste un modo migliore. È solo un semplice sistema per controllare i rilasci del progetto, abbiamo solo versioni principali/secondarie (un punto), quindi float si è sentito come la decisione giusta qui.

class Project < ActiveRecord::Base 
    validates_numericality_of :current_release 
    validates_numericality_of :next_release 
    validate :next_release_is_greater 

    def next_release_is_greater 
     errors.add_to_base("Next release must be greater than current release") unless next_release.to_f > current_release.to_f 
    end 
end 

Questo funziona - passa il test di unità in questione (di seguito per il vostro piacere di osservazione), io sono solo curioso di vedere se c'è un modo più semplice - qualcosa che ho potuto provare il contrario.

unit test Rilevante:

# Fixture data: 
# PALS: 
#  name: PALS 
#  description: This is the PALS project 
#  current_release: 1.0 
#  next_release: 2.0 
#  project_category: 1 
#  user: 1 
def test_release_is_future 
    project = Project.first(:conditions => {:name => 'PALS'}) 
    project.current_release = 10.0 
    assert !project.save 

    project.current_release = 1.0 
    assert project.save 
end 

risposta

19

Come hai notato, l'unico modo è usare un validatore personalizzato. L'opzione: greater_than dovrebbe essere un numero intero. Il seguente codice non funzionerà perché sia ​​la versione corrente che quella successiva sono disponibili solo a livello di istanza.

class Project < ActiveRecord::Base 
    validates_numericality_of :current_release 
    validates_numericality_of :next_release, :greater_than => :current_release 
end 

Lo scopo dell'opzione greater_than è per convalidare il valore contro una costante statica o un altro metodo di classe.

Quindi, non importa e vai avanti con il tuo validatore personalizzato. :)

+0

risposta eccellente, risposta dettagliata - proprio quello che mi serviva (più un po 'di rassicurazione). –

+0

Ottima risposta, correggi l'errore di ortografia quando hai la possibilità "greather_than". Grazie ancora. – ghayes

+0

Fatto, grazie. –

0

Questo è il modo migliore per eseguire la convalida personalizzato, tuttavia, si potrebbe desiderare di guardare in qualcosa di simile a factory_girl in sostituzione di infissi (che sembra che si sta utilizzando):

http://github.com/thoughtbot/factory_girl

tuo test di unità sarebbe quindi simile:

def test_... 
    Factory.create(:project, :current_release => 10.0) 
    assert !Factory.build(:project, :current_release => 1.0).valid? 
end 
4

Con Rails 3.2, è possibile convalidare due campi uno contro l'altro al volo passando in un proc.

validates_numericality_of :next_release, :greater_than => Proc.new {|project| project.current_release } 
6

validates_numericality_of accetta a large list of options e alcuni di essi possono essere forniti con un proc o un simbolo (questo significa che è possibile passare fondamentalmente un attributo o un intero metodo).

per convalidare la numericality di un immobile è superiore a un altro valore:

class Project < ActiveRecord::Base 
    validates_numericality_of :current_release, less_than: ->(project) { project.next_release } 

    validates_numericality_of :next_release, 
    greater_than: Proc.new { project.current_release } 
end 

per chiarire, una di queste opzioni può accettare un proc o un simbolo:

  • :greater_than
  • :greater_than_or_equal_to
  • :equal_to :less_than
  • :less_than_or_equal_to

docs validates_numericality:http://api.rubyonrails.org/classes/ActiveModel/Validations/HelperMethods.html#method-i-validates_numericality_of

utilizzando proc con le convalide: http://guides.rubyonrails.org/active_record_validations.html#using-a-proc-with-if-and-unless

Problemi correlati