Flowdock
method

error_messages_for

Importance_5
error_messages_for(object_name, options = {}) public

Returns a string with a div containing all the error messages for the object located as an instance variable by the name of object_name. 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)

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.

Show source
Register or log in to add new notes.
July 28, 2008
15 thanks

Friendlier error message example

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  %>
August 12, 2008
12 thanks

Overriding the default div class="fieldWithErrors"

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}" }
October 23, 2008
8 thanks

Customizing attribute names in error messages

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.

March 31, 2009 - (v2.0.0 - v2.3.2)
3 thanks

Override fieldWithErrors markup in Rails > v2

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>)}
August 4, 2008
3 thanks

Detailed messages for a nested model

Detailed messages for a nested model

<%@address = @order.address%>
<%=error_messages_for :address%>
October 30, 2008
2 thanks

re: Customizing attribute names in error messages

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.

August 14, 2008
1 thank

Use Hpricot to customise error fields

I like to use Hpricot 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>
October 16, 2008
0 thanks

Only error message

<%= 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>