Last Updated: January 22, 2017
·
13.55K
· leonardofaria

Showing errors messages in Rails 4

The method error_messages_for was deprecated on Rails 2.3.8.
So, I looked for a way to restore the feature. I found two solutions:

Solution 1: Create the partial shared/_error_messages.html.erb

<% if target.errors.any? %>
<div class="error_explanation">
  <h2><%= pluralize(target.errors.count, "error") %> prevented this record from being saved:</h2>
  <ul>
  <% target.errors.full_messages.each do |msg| %>
    <li><%= msg %></li>
  <% end %>
  </ul>
</div>
<% end %>

In the case, you just need render the partial in your form. Example:

<%= form_for @user, :url => user_path do |f| %>
<%= render "shared/error_messages", :target => @user %>
  <p>
    <%= f.label :email %>
    <%= f.text_field :email %>
  </p>
  <p>
    <%= f.label :password %>
    <%= f.password_field :password %>
  </p>
  <p class="actions"><%= f.submit %></p>
<% end %>

Via: https://gist.github.com/kenzie/1213729

Solution 2: Create the helper error_messages_helper.rb

module ErrorMessagesHelper
  # Render error messages for the given objects. The :message and :header_message options are allowed.
  def error_messages_for(*objects)
    options = objects.extract_options!
    options[:header_message] ||= t(:"errors.template.header", model: t(:"activerecord.models.#{objects.compact.first.class.name.downcase}"), count: objects.compact.first.errors.messages.size)
    options[:message] ||= t(:"errors.template.body")
    messages = objects.compact.map { |o| o.errors.full_messages }.flatten
    unless messages.empty?
      content_tag(:div, id: "error_explanation") do
        list_items = messages.map { |msg| content_tag(:li, msg) }
        content_tag(:h2, options[:header_message]) + content_tag(:p, options[:message]) + content_tag(:ul, list_items.join.html_safe)
      end
    end
  end

  module FormBuilderAdditions
    def error_messages(options = {})
      @template.error_messages_for(@object, options)
    end
  end
end

ActionView::Helpers::FormBuilder.send(:include, ErrorMessagesHelper::FormBuilderAdditions)

I adapted the original version (https://gist.github.com/danielboggs/6773673) to support Rails' translations. This gist is availiable here: https://gist.github.com/leonardofaria/bf88d8fb1e5cf1fd2a0b

2 Responses
Add your response

Why would you want to create the error partial in the view helper? All you're doing is inlining the ERB and creating technical debt.

over 1 year ago ·

Actually translation still does not work, because errors.full_messages produces a mix of english and russian (in my case) like so:
<li>fieldnameinenglish errormessageinrussian</li>
But if I run object.errors.full_messages from console, it works correct. I think that include is being called from a wrong place.
Any ideas how to fix?

over 1 year ago ·