Parace que nuestros amigos ActiveRecord::Base.human_name y ActionView::Base::Helpers.error_messages_for parece que no están en la misma onda o ola o como queráis. El método human_name intenta proporcionar un nombre más “humano” a nuestros modelos de active record y error_messages_for intenta proporcionarnos unos bonitos mensajes de error al intentar crear/editar nuestro modelo de active record.
Además error_messages_for tiene multitud de opciones que nos permiten definir enteramente el contenido de los mensajes, su estructura html y otras cosillas. Pero el problema viene cuando tratamos con los valores por defecto. Este método captura la variable de instancia a partir de su primer parámetro y debe obtener la variable options[object_name] de dicha variable si la opción object_name no es pasada como parámetro. Y aquí llegamos a la controversia, ¿Que clave de nuestros locale recuperamos para generar el object_name en caso de que no lo proporcione el programador?
Pues como suponéis error_messages_for no recupera la misma clave que human_name con lo que nos surge un problema.
def error_messages_for(*params)
options[:object_name] ||= params.first
...
I18n.with_options :locale => options[:locale], :scope => [:activerecord, :errors, :template] do |locale|
...
object_name = options[:object_name].to_s.gsub('_', ' ')
object_name = I18n.t(object_name, :default => object_name, :scope => [:activerecord, :models], :count => 1)
...
end
...
end
def human_name(options = {})
defaults = self_and_descendants_from_active_record.map do |klass|
:"#{klass.name.underscore}"
end
defaults << self.name.humanize
I18n.translate(defaults.shift, {:scope => [:activerecord, :models], :count => 1, :default => defaults}.merge(options))
end
Pero ante la llegada inminente de Rails 3 o eso nos comentaba Yehuda en el grupo del core team se han puesto de acuerdo estos muchachos con la ayuda de ActiveModel y tenemos esto.
module ActiveModel::Naming
# Transform the model name into a more humane format, using I18n. By default,
# it will underscore then humanize the class name (BlogPost.model_name.human #=> "Blog post").
# Specify +options+ with additional translating options.
def human(options={})
# No nos interesa que clave recupera pero vemos que será la misma
...
end
end
module ActionView
module Helpers
module ActiveModel
def error_messages_for(*params)
...
if object.class.respond_to?(:model_name)
options[:object_name] ||= object.class.model_name.human.downcase
end
...
end
end
end
end
Así por ahora solo nos queda esperar o pasarle a error_messages_for el parámetro object_name con le valor que necesitemos.
Ciau