Changing the attribute name used by error messages

Is it possible to change the attribute name displayed to the user via
the error_messages_for tag? For example if you wanted to use ‘email’
as an attribute name and db column but ‘e-mail’ as the attribute name
displayed on the webpage. I’m thinking of using the Custom Error
Message plugin (http://wiki.rubyonrails.org/rails/pages/Custom+Error
+Message) but you have to rewrite the whole error message.

Any better ideas?

Eric N. wrote:

Is it possible to change the attribute name displayed to the user via
the error_messages_for tag? For example if you wanted to use ‘email’
as an attribute name and db column but ‘e-mail’ as the attribute name
displayed on the webpage.

ActiveRecord::Base::human_attribute_name is responsible for the
transformation, so you could do this, as long as you don’t mind a little
monkey patch:

put this in your environment.rb

module ActiveRecord
class Base
def self.human_attribute_name(attribute_key_name)
case attribute_key_name
when ‘email’ then ‘E-mail’
else attribute_key_name.humanize
end
end
end
end

This would override the attribute names anywhere they’re humanized for
display (which is probably what you want). Besides error messages, this
includes scaffold templates and other generated code. If you don’t want
that, you should probably just write your own error_messages_for (by
accessing object.errors) as the docs suggest.

One other caveat – there’s a test that covers this, in
/rails/activerecord/test/reflection_test.rb:55
(test_human_name_for_column). It’ll fail if you change the humanization
of a column named ‘author_name’.

Chris K.
http://kampers.net

I was hoping for a slightly more elegant solution that doesn’t require
monkey patching. Also the code states that human_attribute is
deprecated:

  # Transforms attribute key names into a more humane format, such

as “First name” instead of “first_name”. Example:
# Person.human_attribute_name(“first_name”) # => “First name”
# Deprecated in favor of just calling “first_name”.humanize
def human_attribute_name(attribute_key_name) #:nodoc:
attribute_key_name.humanize
end

Thanks for the reply. Any other ideas? I think using the custom error
message plugin might be the best option.

Eric

Eric N. wrote:

I was hoping for a slightly more elegant solution that doesn’t require
monkey patching. Also the code states that human_attribute is
deprecated:

Ha! I can’t believe I wrote that up without seeing the deprecation
comment. Also, that method is still in use elsewhere in the code. I’m
going to get a patch going here in a minute (incl. a nice deprecation
message)…

Anyway, two more options.

  1. You can use this patch to specify new inflections for the humanizer,
    which I suppose (hope!) was the core team’s intent with this
    deprecation. See, e.g. http://dev.rubyonrails.org/ticket/6989

  2. Somebody wrote a plugin. It’s basically just another implementation
    of human_attribute_name, with the ability to override the default call
    to humanize. Sounds like just what you need.
    http://agilewebdevelopment.com/plugins/human_attribute_override

Chris K.
[email protected]

Chris K. wrote:

Eric N. wrote:

I was hoping for a slightly more elegant solution that doesn’t require
monkey patching. Also the code states that human_attribute is
deprecated:

Ha! I can’t believe I wrote that up without seeing the deprecation
comment. Also, that method is still in use elsewhere in the code. I’m
going to get a patch going here in a minute (incl. a nice deprecation
message)…

Behold, a patch. http://dev.rubyonrails.org/ticket/8760

Chris K.
[email protected]