2012-03-17 8 views
7

Ejecuto Ruby (1.9.3) en Rails (3.2.0) y tengo un problema con la validación de atributos virtuales.Validación de atributos virtuales en Ruby on Rails

Tengo un modelo Flight que representa un vuelo que, entre otros, tiene los atributos que representan el aeropuerto de salida y llegada.

Porque la select para seleccionar un aeropuerto es potencialmente enorme, opté por una solución de autocompletar, que funciona perfectamente bien. Estoy usando una devolución de llamada before_validation para rellenar correctamente el ID real del aeropuerto:

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 

El problema es, sin embargo, que cuando el usuario introduce el nombre de un aeropuerto que no existe en la base de datos, la confirmación falla porque la ID de cualquiera de los aeropuertos es nil. Estupendo. Lo que no es grande, sin embargo, es que este error de validación no se refleja en el formulario porque técnicamente, es la entrada para otro 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 %> 

¿Es esto el camino a seguir adecuadamente sobre, transformando el nombre del aeropuerto en una identificación en la devolución de llamada before_validation? Y si es así, ¿cómo puedo obtener los errores de validación para que aparezcan en el atributo de nombre virtual del aeropuerto?

Respuesta

4

Creo que va por buen camino con la devolución de llamada before_validation.

Puede validar atributos virtuales como todos los atributos normales. Entonces todo lo que necesitas es solo una validación en el modelo. Prueba esto:

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

esto debe añadir un error de los errores de los objetos y se debe mostrar el error en su formulario ...

+0

Gracias por la rápida respuesta! Ya tengo validaciones en 'departure_airport' y' arrival_airport'. El problema es que estos no son los campos que representan los 'input' en el formulario. No puedo simplemente validar la presencia porque cuando alguien escribe texto en ellos, el campo está presente, pero el objeto real del 'Aeropuerto' va a faltar. – Laurens

+0

Es por eso que registra la devolución de llamada 'before_validation'. Cuando el usuario ingresa en un galimatías, no encuentra el aeropuerto y la validación falla. Se agregará un error y se mostrará al usuario. Tal vez deberías considerar agregar un masaje de error personalizado. – klump

+0

Lo siento mi mal. Yo no lo entiendo. Tal vez necesites tu propio método de validación. Puede agregar errores al objeto con 'self.errors.add (: fieldname," message ")'. Si ahora usa el 'departure_airport_name' como nombre de campo y agrega un mensaje, se mostrará en el campo' departure_airport_name'. – klump