error_messages_for you

Making pretty error messages is easy. And fun! I overwrote error_messages_for because I wanted to include multiple objects in the error message list. Then I freaked out and loaded it up with lotsa functionality.

  • Print error messages for multiple objects by listing them in an array. Objects can be specified:
    • The object. (@user or non_instance_object)
    • Specify objects as a string representing the name of an instance variable ('email_address' to refer to @email_address)

<%= error_messages_for [@user, 'email_address', non_instance_object] %>

<%= error_messages_for 'non_instance_object' %>

  • Customize the header message or the sub header message

<%= error_messages_for 'user', :header_message=>'%d errors prohibited you from creating a happy pony party.', :header_sub_message=> 'these ponies were bad:' -%>

  • Skip or customize the field name display. Perhaps in one context you call it “Primary email address” and in another, you refer to it as “Contact Information”. Or you just dont want to report errors on the field.

<%= error_messages_for 'user', :sub=>{'email_address_text'=>'Primary Email Address'}, :skip=>['credit_card_number'] -%>

  • Compatible with the awesome globalize plugin. (If you don’t like global things, then you should remove the .t business.

Codeage:

def error_messages_for(object_list, options = {})
return "" if object_list.nil?
options = options.symbolize_keys
bullets,main_obj_name = bullets_from_errors(object_list, options)
if !bullets.blank?
#default to standard error message. replace the ${NUM_ERRORS} with the number of errors.
options[:header_message] ||= "%d errors prohibited this %1 from being saved".t(nil,bullets.length).gsub('%1',"#{(main_obj_name || 'object').t}")
options[:header_message] = options[:header_message] % bullets.length


content_tag("div",
content_tag( options[:header_tag] || "h2", options[:header_message]) +
content_tag("p", (options[:header_sub_message] || "There were problems with the following fields:").t) +
content_tag("ul", "#{bullets}"),
"id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation"
)
else
""
end

end

Grab the all the code

8 Responses to error_messages_for you

  1. leslie says:

    A tip for you guys, it’s not hard to write JRuby to sync up with Google Calendar, by way of GData.

    An example: http://jinsync.com

    Cheers!

    ~L

  2. Nalin Mittal says:

    Where do I place the code to override the default helper?

  3. blythe says:

    Code can go in ApplicationHelper. Or if you have base controller class you can add it to its helper.

  4. DJPaul says:

    Thanks

  5. thirstydoh says:

    Great stuff, thanks!
    Btw I like this syntax more:

    options[:header_message] ||= sprintf("%d errors prohibited this %s from being saved".t, bullets.length ,"#{(main_obj_name || 'object').t}")
    
  6. thirstydoh says:

    One thing, there’s a line:

    object.errors.each do |attr, msg|
    #…
    msg_list << content_tag('li', "#{obj_name} #{msg}".t("#{obj_name.t} #{msg.to_s.t}")) end [/sourcecode] msg here is actually an array like ['is too long (maximum is %d characters)', 50] and if it has non-nil parameters like in case of validates_length_of this will output smth like 'Field is too long (maximum is %d characters)50'. It can be fixed with [sourcecode language='ruby'] msg[0] = msg[0].t msg_list << content_tag('li', "#{obj_name.t} #{sprintf(*msg)}") [/sourcecode]

  7. jim says:

    Sorry for the stupid queston but “If you don’t like global things, then you should remove the .t business.” when i just copied the code in and ran this the first time i got an undefined method `t’ what am i doing wring?

  8. […] But how to do that without diving into Authlogic’s nicely maintained internals?  You could override error_messages_for, but that’s overkill for this single case.   Rails doesn’t let you remove individual items […]

Leave a comment