nested error_messages_for
Mar 6th, 2008 by scott
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.
object = instance_variable_get("@#{object}") if ([Symbol, String].member? object.class)
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.
Scott Nedderman is the founder of Netphase.com, a consulting practice that specializes in building web applications for Internet startups. He is also a vocalist, plays guitar and penny whistle, occasionally performs in musicals, enjoys camping and is a homeschooling father of 6.




This is a really cool method, thank you, already using it!!