nested error_messages_for
I think lots of folks have run into this problem of using error_messages_for to display errors of nested or subordinate objects. The current Rails method doesn’t handle it well. In addition, there’s the problem of not being able to specify the full message. So… I tackled this problem today and came up with a pretty good solution using recursion.
def nested_error_messages_for(object) if ([Symbol, String].member? object.class) object = instance_variable_get("@#{object}") end unless object.nil? || object.errors.count.zero? error_messages = object.errors.to_a.uniq.map do |key, value| object2 = object.send(key) if object2.is_a?(Array) object2.collect {|obj| content_tag(:li, nested_error_messages_for(obj)) } elsif object2.is_a?(ActiveRecord::Base) content_tag(:li, nested_error_messages_for(object2)) elsif value.match(/^\^/) content_tag(:li, value[1..value.length]) else content_tag(:li, "#{key.underscore.split('_').join(' ').humanize} #{value}") end end content_tag(:div, content_tag(:div, "#{object.class} has errors", :class => 'error_field') + content_tag(:ul, error_messages), :class => 'error_block') else '' end end
To use it, just replace your current call to error_messages_for with nested_error_messages_for. There’s nothing extra that needs to be done in the controller as with some recipes. You’ll also want to make it look good with some CSS.
I’m pretty sure there’s more that could be done with this, but thought I’d present it here first and try to get some feedback before turning it into a gem. Let me know how it works for you.
2 Comments to “nested error_messages_for”
Leave a Reply

This is a really cool method, thank you, already using it!!
Thank you very much, that’s what I was going to code, but found out you already has done that