customize active record attribute display name in error message

Is there an easy way to customize the display name of the attributed
used in a validation error message. For example, let's say I have an
active record with the attribute :msg that is validated for presence.
If is doesn't exist I don't want the user to see "msg can't be
blank!" I want it to say "Message can't be blank!" Is there an easy
way to do that?

Hi drewB,

You can change the "humanized" version of that symbol when it's
accessed via human_attribute_name.

Try this:

class Post < ActiveRecord::Base

  HUMANIZED_COLUMNS = {:msg => "Message"}

  def self.human_attribute_name(attribute)
    HUMANIZED_COLUMNS[attribute.to_sym] || super
  end
end

HTH,
Richard

I responded just a bit ago, but I don't see my response, so hopefully
there won't be two responses...

Essentially, Drew, you can map the column to be something else when
you call "humanize" on it. Try this:

class Post < ActiveRecord::Base

  HUMANIZED_COLUMNS = {:msg => "Message"}

  def self.human_attribute_name(attribute)
    HUMANIZED_COLUMNS[attribute.to_sym] || super
  end
end

HTH,
Richard

Have you read the validation documentation?

All of the Rails validators support a :message option, for example
look at validates_presence_of:

http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M002164

See where it says "message - A custom error message (default is:
"can‘t be blank")." ? That means when you write

validates_presence_of :foo, :message => "Message can't be blank!"

I am aware of the :message option. What I was hoping to do is be able
to use many of the default messages and just change the attribute name
displayed. For example, something like:

attr_display_name :msg "Message"

I responded just a bit ago, but I don’t see my response, so hopefully there won’t be two responses…

Essentially, Drew, you can map the column to be something else when you call “humanize” on it. Try this:

class Post < ActiveRecord::Base

HUMANIZED_COLUMNS = {:msg => “Message”}

def self.human_attribute_name(attribute)
HUMANIZED_COLUMNS[attribute.to_sym] || super
end
end

HTH,
Richard

That is exactly what I was looking for! Thank you!

Hi
    I was just trying this My models and relations are as
company has_many users
user belongs_to company

      And when saving a user a company is also saved So in user model I
have
validates_associated :company

         The solution works perfectly for user model attributes. But it
is not working for company attributes. For example in companies table i
have address_city field And as the solution suggests I add to company
model below code

HUMANIZED_COLUMNS = {:address_city => "City"}

  def self.human_attribute_name(attribute)
    HUMANIZED_COLUMNS[attribute.to_sym] || super
  end

            But this is not working It shows Address city .But I need is
City. Please help

Thanks
Tom

Hi
    One more thing is ,in order to show validates_associated error
message than the regular message "is invalid" I am using the hack in
environment.rb like

module ActiveRecord::Validations::ClassMethods
  def validates_associated(*associations)
      associations.each do |association|
        class_eval do
          validates_each(associations) do |record, associate_name,
value>
            associates = record.send(associate_name)
            associates = [associates] unless
associates.respond_to?('each')
            associates.each do |associate|
              if associate && !associate.valid?
                associate.errors.each do |key, value|
                  record.errors.add(key, value)
                end
              end
            end
          end
        end
      end
  end
end

I could solve the problem the following way. But I dont know whether
this the right approach.Please correct if wrong

module ActiveRecord::Validations::ClassMethods
  def validates_associated(*associations)
      associations.each do |association|
        class_eval do
          validates_each(associations) do |record, associate_name,
value>
            associates = record.send(associate_name)
            associates = [associates] unless
associates.respond_to?('each')
            associates.each do |associate|
              if associate && !associate.valid?
                associate.errors.each do |key, value|

                    humanized_columns = {:address_city =>
"City",:phone_oofice => "Office Phone Number"}
                    record.errors.add(key, value,{:attribute =>
humanized[key.to_sym] || human_attribute_name(key.to_s)})

                end
              end
            end
          end
        end
      end
  end
end

Thanks
Tom

I would just like to add that those who uses I18n can easily add these
model "translations" to the localization file like so:

en:
  activerecord:
    models:
      user: "User"
      company: "Company"
    attributes:
      user:
        login: "Username"
        password. "Password"
      company:
        name: "Company name"

I prefer this method over having the HUMANIZED_COLUMNS in every model.

I18n can also be used to customize error messages, if you dont like the
default ones (like "is invalid"). This is certanly a lot cleaner than
hacking active record.

Hi
Thanks for replying back.Can you please paste a good link explains how
to do this?

Tom

You mean how to use I18n?
Ryan Bates has a screen cast on it:
http://railscasts.com/episodes/138-i18n
And then there's the official I18n guide
http://guides.rubyonrails.org/i18n.html

Sharagoz -- wrote:

You mean how to use I18n?
Ryan Bates has a screen cast on it:
http://railscasts.com/episodes/138-i18n
And then there's the official I18n guide
http://guides.rubyonrails.org/i18n.html

Unfortunately, Rails' official I18N is quite cumbersome. I highly
recommend fast_gettext.

Best,