Terry Bu
Terry Bu

Reputation: 899

Creating better error messages in the View for Rails

I am experimenting with a simple people/new page to practice showing error messages. Right now, with the below set-up, the error messages display okay but look a little awkward because the text says "Firstname can't be blank", "Lastname can't be blank" and so forth. Basically I want the text to say "First Name can't be blank" and "Last Name can't be blank" (with spaces), but I'm assuming the error messages are just following the attribute names I defined in the Model, and there's really no way to change those explicitly.

So how can I change that? Can I not achieve that change without making changes to this particular partial? (shared_error_messages)

Thanks, Screenshot of the new view below. enter image description here

people_controller.rb

class PeopleController < ApplicationController

def new
    @person = Person.new
    @people = Person.all
end

def create
    @person = Person.new(person_params)
    if @person.save
        redirect_to new_person_path
    else
        render 'new'
    end 
end

    private
      def person_params
        params.require(:person).permit(:firstname, :lastname, :age)
      end

end

person.rb

class Person < ActiveRecord::Base
    validates :firstname, presence: true, length: {maximum: 15}, format: { with: /\A[a-zA-Z]+\z/,
    message: "only allows letters" }
    validates :lastname, presence: true, length: {maximum: 15}, format: { with: /\A[a-zA-Z]+\z/,
    message: "only allows letters" }
    validates :age, presence: true, length: {maximum: 3}
end

new.html.erb

Enter your information
<hr>

<%= form_for @person do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  First Name: <%= f.text_field :firstname %><br>
  Last Name: <%= f.text_field :lastname %><br>
  Age: <%= f.number_field :age %><br>
  <%= f.submit "See Your Life Clock" %>
<% end %>

shared/_error_messages

<% if object.errors.any? %>
<div id="error_explain">
  <h2><%= pluralize(object.errors.count, "error") %> prohibited this from being saved to DB</h2>
  <ul>
  <% object.errors.full_messages.each do |msg| %>
    <li><%= msg %></li>
  <% end %>
  </ul>
</div>
<% end %>

Upvotes: 2

Views: 1130

Answers (2)

Bangash
Bangash

Reputation: 1172

An old question, but may be someone facing the same problem benefit from it, so I'm answering it.

In the view you used something like First Name: <%= f.text_field :firstname %> better to use something as follows which will give you good field names by default in your situation.

<%= f.label :firstname, 'First Name' %><br>
<%= f.text_field :firstname %>

Upvotes: 0

gwcoffey
gwcoffey

Reputation: 5921

Assuming you're using Rails 3.2 or later, the "best" way to do this is with localization. Edit your en.yml file and add this:

en:
   activerecord:
      attributes:
         person:
            firstname: "First Name"
            lastname: "Last Name"

The error reporting system will look up human-friendly names for your attributes from the localization file. Thie may seem heavy-handed, but in my opinion it is the best way because these names will be accessible anywhere, centralized, and easy to maintain.

If you need the friendly name in your own code, (for example, in a label on an edit form or a column header in a list table) you can access it like this:

Person.human_attribute_name(:firstname)

Now if you change the en.yml, the change will reflect throughout your site. And should you ever need to localize to another language, you're on the right track already.

If this is too much for you, you can change your validations to have complete sentences for their messages, and then change your _error_messages partial to look like this:

<% if object.errors.any? %>
   <div id="error_explain">
     <h2><%= pluralize(object.errors.count, "error") %> prohibited this from being saved to DB</h2>
     <ul>
     <% object.errors.each do |attr, msg| %>
       <li><%= msg %></li>
     <% end %>
     </ul>
   </div>
<% end %>

Upvotes: 3

Related Questions