4

I have the following code to display error messages:

<% if @profile.errors.any? %>
    <% puts @profile.errors.full_messages.inspect.to_s %>
    <ul>
      <% @profile.errors.full_messages.each do |msg| %>
        <% puts 'errors ared' + msg.to_s %>
        <li><%= msg %></li>
      <% end %>
    </ul>
<% end %>

Here is the validation in the model:

validates :title, presence: true, length: {maximum: 50, minimum: 5, too_long: "Title cannot be longer than %{count} characters", too_short:" must be at least %{count} characters."}

For some reason, this prints both the name of the attribute with the error and the error. For example, if I am trying to display the error from updating a form field called "title", the error message will read:

Title Title cannot be longer than 50 characters

I have many error messages I want to display throughout my site and I don't want anything being written automatically. How do I get rid of the word "Title" at the beginning?

Philip7899
  • 4,599
  • 4
  • 55
  • 114
  • Remove "Title" from `too_long: "Title cannot be longer...`? Seems like it will automatically prepend it. – Matt Feb 25 '14 at 22:19
  • Yes, that will fix this problem, but this was just an example. I'd like to know how to fix the issue of rails prepending the attribute to the error message. – Philip7899 Feb 25 '14 at 22:21
  • Seems that in Rails 3 one customizes error messages using locales: http://stackoverflow.com/questions/808547/fully-custom-validation-error-message-with-rails I don't know if there is a better way in Rails 4. – Matt Feb 25 '14 at 22:26
  • @Philip7899 I wrote a customized implementation for your code. Please see my updated answer in the EDIT section – Kirti Thorat Feb 25 '14 at 22:52

2 Answers2

2

full_messages method prepends attribute name to the validation error message. Following is the method implementation in rails

## Following code is extracted from Rails source code

def full_messages
      map { |attribute, message| full_message(attribute, message) }
end

def full_message(attribute, message)
      return message if attribute == :base
      attr_name = attribute.to_s.tr('.', '_').humanize
      attr_name = @base.class.human_attribute_name(attribute, default: attr_name)
      I18n.t(:"errors.format", {
        default:  "%{attribute} %{message}",
        attribute: attr_name,
        message:   message
      })
 end

If you see the full_messages method it in turn calls full_messages wherein attribute gets prepended to the error message. So, if you add attribute name in the validation error message it is definitely going to be duplicated which is what is happening in your case.

In nutshell, you don't need to specify attribute name in validation message, as rails is already taking care of it.

EDIT

Nothing is impossible. If you want you could customize it as below

<% if @profile.errors.any? %>
    <ul>
      <% @profile.errors.messages.each do |attr, msg| %>
        <% msg.each do |val| %>
        <li><%= val %></li>
        <% end %>
      <% end %>
    </ul>
<% end %>
Kirti Thorat
  • 52,578
  • 9
  • 101
  • 108
0

I would use a message like this. I think this solves your problem.

validates :title, presence: true, length: { maximum: 50, minimum: 5, message: 'Title should be between 5 and 50 characters' }

Then in the view

  <% @profile.errors.each do |attr, msg| %>
    <% puts 'errors ared' + msg.to_s %>
    <li><%= msg %></li>
  <% end %>

The key is to use errors instead of full_messages and then split each error in attr and msg and get only the message or compose the message as one likes.

Rafa Paez
  • 4,820
  • 18
  • 35