
Para los que no desarrollamos aplicaciones en inglés hay ciertas funcionalidades de serie de ActiveRecord que no se adaptarán a nuestras necesidades, como puede ser el caso de los errores de validación de un modelo.
ActiveRecord permite, para cada regla de validación, indicar el mensaje de error que se mostrará al usuario cuando no se cumple dicha validación. El problema es que dicho mensaje se concatena al nombre del atributo. Así, si nuestro atributo se llama name y queremos validar su longitud indicaremos:
validates_length_of :name, :minimum => 1, :message => "es demasiado corto"
Y cuando se produzca el error de validación el mensaje mostrado al usuario será: "name es demsiado corto".
Lo ideal sería que ActiveRecord no concatenara el nombre del atributo al mensaje de error, pero ya se sabe que el DRY lo llevan hasta estos extremos y nos evitan tener que escribir el nombre del atributo en la validación y en el mensaje de error.
Sin embargo hay una forma muy sencilla de hackear (o saltarnos a la torera, vaya) este comportamiento redefiniendo un par de acciones y permitir que si definimos un mensaje de error en la validación que indique ya de qué atributo se trata, luego no muestre el nombre del atributo en el mensaje de error, y éste quede tal cuál lo indicamos en la regla de validación.
Por ejemplo:
validates_length_of :name, :minimum => 1, :message => "El nombre introducido es demasiado corto"
Para ello, primero redefiniremos el método full_messages de ActiveRecord, sustituyendo la línea comentada por la de inmediatamente abajo, que elimina el nombre del atributo en la cadena resultado:
def full_messages
full_messages = []
@errors.each_key do |attr|
@errors[attr].each do |msg|
next if msg.nil?
# full_messages << @base.class.human_attribute_name(attr) + " " + msg
full_messages << msg
end
end
return full_messages
end
Y puestos ya, para terminar el trabajo y que todos los mensajes salgan en castellano, podemos redefinir el helper error_messages_for, que escribe el texto informando al usuario que ha habido errores en perfecto inglés.
Todo ello lo podemos juntar en un único fichero (que podéis descargar de aquí) e incluirlo en la carpeta lib/ de nuestra aplicación, para después cargarlo desde el config/environment.rb y tener la redefinición a punto.
En realidad es un ejercicio bastante sano el redefinir partes de Rails, siempre que esto nos ayude a que nuestra aplicación sea más sencilla y clara. Es decir, Rails y ActiveRecord nos dan la sopa con todos sus ingredientes (convención sobre configuración, framework con opinión, etcétera), pero nosotros podemos añadir y quitar los que queramos, para que la sopa quede a nuestro gusto (la flexibilidad de Ruby).
Si habéis visto o leído la presentación de Xavier Noria en la Conferencia de Rails (el enlace no es de la presentación en sí, que creo que Xavier no la ha colgado), titulada "Rails desde el código", os habréis dado cuenta de lo dinámico que es Ruby, y que permite hacer cosas como la que yo os acabo de enseñar.
foto: sopa de ramel personalizada, http://flickr.com/photos/stephanieho/163018565/

13 Dic 2006 | 10:54 AM
Bueno, traté de dejarte un comentario pero no tuve suerte. Te mando un mail. Saludos!
20 Dic 2006 | 04:37 PM
Muy interesante!, justo ayer estuve peleándome con este tema. En mi caso aún más complicado por utilizar GetText. Supongo que finalmente tendrémos que implementar algo parecido a lo que propones, pero sobre las librerías de GetText (que a su vez redefinen el comportamiento por defecto de ActiveRecord)
21 Dic 2006 | 08:19 AM
Hola Luismi,
la verdad es que mi experiencia con GetText es nula, pero supongo que el procedimiento será el mismo.
Por cierto, a raíz de este post Ariel Hernán me envió el siguiente plugin: http://www.railtie.net/articles/2006/01/26/enhancing_rails_errors... que tiene una pinta estupenda y es mucho más flexible y pontente que lo que yo propongo.
Espero que te sirva.
28 Ene 2007 | 07:06 PM
sdf
8 Dic 2007 | 08:38 AM
不锈钢管
无缝钢管
8 Dic 2007 | 08:46 AM
不锈钢管
无缝钢管
塑料衣架
塑料衣架
塑料衣架供应商
分切机
磁铁
传真软件
混水阀
20 Jun 2008 | 11:13 AM
¡Gracias!