Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: Field names

I have a User model with an 'email' field.

In my view, I have rendered the label for this field as 'Email address' as follows:

<%= form_for(:user) do |f| %>
  <%= f.label :email, 'Email address' %><br /
  <%= f.text_field :email %>
<% end %>

However, when validation errors are generated, 'Email' is used instead:

Email is invalid

Is there something I can add to the model so that :email always renders to 'Email address' rather than simply 'Email'?

Many thanks

like image 264
gjb Avatar asked Nov 02 '10 12:11

gjb


People also ask

How do you change the name of a column in Ruby on Rails?

rename_column(table_name, column_name, new_column_name): Renames a column but keeps the type and content. See also documentation for rename_column .

What are migrations in Rails?

A Rails migration is a tool for changing an application's database schema. Instead of managing SQL scripts, you define database changes in a domain-specific language (DSL). The code is database-independent, so you can easily move your app to a new platform.

What is ActiveRecord base?

Active Record. Active Record objects don't specify their attributes directly, but rather infer them from the table definition with which they're linked. Adding, removing, and changing attributes and their type is done directly in the database. Any change is instantly reflected in the Active Record objects.

What is Rails ApplicationRecord?

ApplicationRecord inherits from ActiveRecord::Base , which defines a number of helpful methods. You can use the ActiveRecord::Base.table_name= method to specify the table name that should be used: class Product < ApplicationRecord self.


2 Answers

You don't need to rename your table columns to do this. There's a very clean fix:

class User < ActiveRecord::Base
  HUMAN_ATTRIBUTE_NAMES = {
    :email => 'Email address',
    :first_name => 'First name'
  }

  class << self
    def human_attribute_name attribute_name
      HUMAN_ATTRIBUTE_NAMES[attribute_name.to_sym] || super
    end
  end
end

What we've done is create a hash of attributes where we want to customize the names. You don't have to list all of them, since many attribute names will work out of the box as you want them to. Then we override ActiveRecord's human_attribute_name method, to try to find the name in our hash first.

This does two really cool things: you no longer have to specify custom labels in your forms, and your error messages will have the new names automatically, as well! As a bonus, you can now use these names wherever you want, by calling:

<%= User.human_attribute_name(:email) %>

This creates a more unified approach to naming. If you want to change "email" to "e-mail" next week, you only have to do it in one place.

I hope this helps!

like image 79
Jaime Bellmyer Avatar answered Sep 17 '22 14:09

Jaime Bellmyer


Expanding gjb comments, I just added this to config/initializers/inflections.rb:

ActiveSupport::Inflector.inflections do |inflect|
    inflect.human 'email', 'Email address' 
end

I think this is much neater.

like image 27
Martin Capodici Avatar answered Sep 17 '22 14:09

Martin Capodici