2012-03-17 8 views
7

Sto eseguendo Ruby (1.9.3) su Rails (3.2.0) e ho un problema con la convalida degli attributi virtuali.Validazione degli attributi virtuali in Ruby on Rails

Ho un modello Flight che rappresenta un volo che, tra gli altri, ha attributi che rappresentano l'aeroporto di partenza e di arrivo.

Poiché il select per la selezione di un aeroporto è potenzialmente enorme, ho optato per una soluzione di completamento automatico, che funziona perfettamente bene. Sto usando un callback before_validation per popolare correttamente l'ID effettivo dell'aeroporto:

before_validation do 
    self.departure_airport = Airport.find_by_long_name(departure_airport_name) 
    self.arrival_airport = Airport.find_by_long_name(arrival_airport_name) 
end 

Il problema è, tuttavia, che quando l'utente inserisce il nome di un aeroporto che non esiste nel database, il commit fallisce perché l'ID di entrambi gli aeroporti è nil. Grande. Ciò che non è grande, tuttavia, è che questo errore di convalida non si riflette sulla forma perché tecnicamente, è l'input per un altro campo:

validates :departure_airport, :arrival_airport presence: true 

attr_accessor :departure_airport_name, :arrival_airport_name 

<%= f.input :departure_airport_name %> 
<%= f.input :arrival_airport_name %> 

E 'questo anche il modo di andare correttamente su, trasformando il nome dell'aeroporto in un ID nel callback before_validation? E se sì, come posso ottenere che gli errori di validazione vengano visualizzati sull'attributo del nome virtuale dell'aeroporto?

risposta

4

Penso che stiate andando nel modo giusto con il callback before_validation.

È possibile convalidare attributi virtuali come ogni attributo normale. Quindi tutto ciò di cui hai bisogno è solo un po 'di validazione nel modello. Prova questo:

validates :departure_airport, presence: true 
validates :arrival_airport, presence: true 

questo dovrebbe aggiungere un errore agli errori oggetti e deve essere visualizzato l'errore nel modulo ...

+0

Grazie per la risposta rapida! Ho già delle convalide su 'departure_airport' e' arrival_airport'. Il problema è che questi non sono i campi rappresentati da 'input' sul modulo. Non posso semplicemente convalidare la presenza perché quando qualcuno digita il testo in essi, il campo è presente, ma l'oggetto 'Airport' non sarà presente. – Laurens

+0

Ecco perché si registra il callback 'before_validation'. Quando l'utente entra in un linguaggio senza senso, non troverà l'aeroporto e la convalida fallirà. Un errore verrà aggiunto e visualizzato all'utente. Forse dovresti prendere in considerazione l'aggiunta di un massaggio di errore personalizzato. – klump

+0

Scusate il mio male. Non l'ho capito. Forse hai bisogno del tuo metodo di convalida. È possibile aggiungere errori all'oggetto con 'self.errors.add (: fieldname," message ")'. Se ora usi il parametro 'departure_airport_name' come nome di campo e aggiungi un messaggio, verrà visualizzato nel campo 'departure_airport_name'. – klump