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
Written by Leonardo Faria
Related protips
2 Responses
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.
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?