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/