method

error_messages_for

rails latest stable - Class: ActionView::Helpers::ActiveRecordHelper

Method deprecated or moved

This method is deprecated or moved on the latest stable version. The last existing version (v2.3.8) is shown here.

error_messages_for(*params)
public

Returns a string with a DIV containing all of the error messages for the objects located as instance variables by the names given. If more than one object is specified, the errors for the objects are displayed in the order that the object names are provided.

This DIV can be tailored by the following options:

  • :header_tag - Used for the header of the error div (default: "h2").
  • :id - The id of the error div (default: "errorExplanation").
  • :class - The class of the error div (default: "errorExplanation").
  • :object - The object (or array of objects) for which to display errors, if you need to escape the instance variable convention.
  • :object_name - The object name to use in the header, or any text that you prefer. If :object_name is not set, the name of the first object will be used.
  • :header_message - The message in the header of the error div. Pass nil or an empty string to avoid the header message altogether. (Default: "X errors prohibited this object from being saved").
  • :message - The explanation message after the header message and before the error list. Pass nil or an empty string to avoid the explanation message altogether. (Default: "There were problems with the following fields:").

To specify the display for one object, you simply provide its name as a parameter. For example, for the @user model:

  error_messages_for 'user'

To specify more than one object, you simply list them; optionally, you can add an extra :object_name parameter, which will be the name used in the header message:

  error_messages_for 'user_common', 'user', :object_name => 'user'

If the objects cannot be located as instance variables, you can add an extra :object parameter which gives the actual object (or array of objects to use):

  error_messages_for 'user', :object => @question.user

NOTE: This is a pre-packaged presentation of the errors with embedded strings and a certain HTML structure. If what you need is significantly different from the default presentation, it makes plenty of sense to access the object.errors instance yourself and set it up. View the source of this method to see how easy it is.

8Notes

Friendlier error message example

autonomous · Jul 28, 200815 thanks

The default error messages can be a bit stale and off putting. Try somethings like this:

error_messages_for( :user, :header_message => "Oops - We couldn't save your user!", :message => "The following fields were a bit of a problem:", :header_tag => :h1 )

You can also use error_messages_for as follows <% form_for User.new do |f| %> <%= f.error_messages :header_message => "..." %> <% end %>

Overriding the default div class="fieldWithErrors"

hosiawak · Aug 12, 200812 thanks

By default fields that are invalid are wrapped in:

<div class="fieldWithErrors">
<input type="text" name="blah">
</div>

To override and wrap in spans instead of divs place the following in your environment.rb:

ActionView::Base.field_error_proc = Proc.new { |html_tag, instance| "<span class=\\"fieldWithErrors\\">#{html_tag}</span>" }

or to not use wrapping at all:

ActionView::Base.field_error_proc = Proc.new { |html_tag, instance| "#{html_tag}" }

Customizing attribute names in error messages

tarvaina · Oct 23, 20088 thanks

By default, the error messages translate the names of the attributes through String#humanize. The way to to change that is to override the ActiveRecord::Base.human_attribute_name method.

For example, if you want to name a column in your database as :www_url and you want to say "Website" instead of "Www url" in the error message, you can put this into your model:

class Person < ActiveRecord::Base
def self.human_attribute_name(attribute_key_name)
  if attribute_key_name.to_sym == :www_url
    "Website"
  else
    super
  end
end
end

Currently this seems to be the cleanest and easiest way. Unfortunately, human_attribute_name is deprecated and may stop working in a future release of Rails.

Detailed messages for a nested model

grosser · Aug 4, 20083 thanks

Detailed messages for a nested model

<%@address = @order.address%>
<%=error_messages_for :address%>

Override fieldWithErrors markup in Rails > v2

greenideas · Mar 31, 20093 thanks

The code posted by @hosiawak will still work in recent versions of Rails, but maybe a more current, idiomatic way to do it is to stick this inside the Rails::Initializer block in environment.rb (obviously you'll also need to restart your server to pick up the config change):

config.action_view.field_error_proc = Proc.new {|html_tag, instance| 
%(<span class="fieldWithErrors">#{html_tag}</span>)}

re: Customizing attribute names in error messages

roywblack · Oct 30, 20082 thanks

You can use Module.alias_attribute to achieve the same result as overriding human_attribute_name. After aliasing use the new name in the validates_xxxx_of methods or ActiveRecord::Errors.add.

Use Hpricot to customise error fields

rob-twf · Aug 14, 20081 thank

I like to {use Hpricot}[http://www.thewebfellas.com/blog/2008/4/21/error-fields-with-a-hpricot-twist] to add error information to my form fields. Here's an example:

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
if html_tag =~ /<(input|label|textarea|select)/
  error_class = 'error'
  nodes = Hpricot(html_tag)
  nodes.each_child { |node| node[:class] = node.classes.push(error_class).join(' ') unless !node.elem? || node[:type] == 'hidden' || node.classes.include?(error_class) }
  nodes.to_html
else
  html_tag
end
end

This will only apply the CSS class 'error' to elements that aren't hidden inputs and don't already have the error class.

Sample output:

<div>
<label class="error" for="user_email">Email</label>
<input name="user[email]" size="30" class="error" type="text" id="user_email" value="" />
</div>

Only error message

RobinWu · Oct 16, 2008

=== <%= error_messages_for :order, :header_message => nil, :message => nil %>

Browser view code

<div id="errorExplanation" class="errorExplanation">
<ul>
  <li>Weight 只有 1000.0</li>
  <li>Volume 只有 10.0</li>
</ul>
</div>