2012-01-13 13 views
16

Sono abbastanza nuovo a Rails e io ora sono imbattuto in un problema che non ero in grado di risolvere con il mio amico Google :)Rails - Come convalidare un campo solo se un altro campo ha un determinato valore?

Nella mia forma ho un Select con tre valori: di Apple, Banana e Ciliegia. Se scelgo Apple dalla selezione nascondo un altro Seleziona- e un campo di testo con alcuni Javascript, perché quando si seleziona Apple, non è più necessario compilare questi altri due campi.

Così ora ho un problema con la convalida del mio modulo quando è inviato. Ho trovato alcuni problemi simili, ad esempio nel caso di "Convalida un campo solo se un altro è vuoto."

Questo problema è stato risolto in questo modo:

validates_presence_of :mobile_number, :unless => :home_phone? 

Così ho appena provato la prima cosa che mi é venuta in mente:

validates_presence_of :state, :granted_at, :if => :type != 1 

Ma quando l'eseguo, ottengo questo errore :

undefined method `validate' for true:TrueClass 

Così ora non ho trovato come posso accedere ai valori dall'oggetto che è stato creato ... vi ringrazio in anticipo per il vostro aiuto e spero che la mia domanda non è così ovvia come sembra :-)

risposta

27

Perché è codice eseguibile è necessario avvolgerlo in un lambda o di un oggetto Proc in questo modo:

validates_presence_of :state, :granted_at, :if => lambda { |o| o.type != 1 } 

# alternatively: 
..., :if => lambda { self.type != 1 } 
..., :if => Proc.new { |o| o.type != 1 } 
..., :if ->(o) { o.type != 1 } 
+0

ringraziamento per la risposta veloce :) ma cosa contiene questa variabile di blocco "o"? l'oggetto che viene validato? – TehQuila

+0

Sì, esattamente. Dai anche un'occhiata alla risposta di @ Hauleth dove puoi trovare altri modi per risolvere il tuo problema. Il riferimento definitivo può essere trovato nella documentazione dell'API Rails: http://ar.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html sperare che sia d'aiuto. Inoltre ti suggerisco di google per "ruby procs and blocks" per conoscere i blocchi di base (rubino) dietro a questo. Spero possa aiutare. – Matt

21

È possibile utilizzare if bandiera e lambda:

validates_presence_of :state, :granted_at, :if => lambda {self.type != 1} 

O semplicemente creare metodo privato:

validates_presence_of :state, :granted_at, :if => :valid_type? 

private 
def valid_type? 
    type != 1 
end 
1

anche se le modalità di cui sopra sono le migliori pratiche, ma si può anche rendere più semplice come questo:

validates_presence_of :state, :granted_at, :if => "type!=1" 
1

Sulla base delle risposte precedenti, è anche possibile utilizzare una più breve "freccia" sintassi

validates :state, :granted_at, presence: true, if: ->(o) { o.type != 1 } 
Problemi correlati