I just want to bring a new little piece here:
So I found an easier way to get the result that "AnApprentice" wanted.
First of all, if you want to customize anything within the Devise plug-in, I highly advise you to copy past the code from "\Ruby_repertory\lib\ruby\gems\1.9.1\gems\devise-version\app\controllers|helpers|mailers..." to the file you want in your project.
[Edit] Or you can make your file inherit from the "normal" devise files... Like... say... You want to overwrite only one function within the devise/registrations_controller.rb, the first line of your Users custom registrations controller would be:
class Users::RegistrationsController < Devise::RegistrationsController
[Edit August 7th 2013] Now Devise even provides a tool to generate controllers: https://github.com/plataformatec/devise/wiki/Tool:-Generate-and-customize-controllers
So... anyway... I managed to get what "AnApprentice" wanted just writing this (for a cleaner solution, see the following big edit) :
#/my_project/app/helpers/devise_helper.rb
module DeviseHelper
def devise_error_messages!
return "" if resource.errors.empty?
return resource.errors
end
end
And, in my view, the next lines worked pretty well:
<% devise_error_messages!.each do |key, value| %>
<div class="flash <%= key %>"><%= key %> <%= value %></div>
<% end %>
Well... then you can access to errors for a specific attribute like this:
#Imagine you want only the first error to show up for the login attribute:
<%= devise_error_messages![:login].first %>
And... A little trick to have only one error (the first to get catched) showing up per attribute:
<% if resource.errors.any? %>
<% saved_key = "" %>
<% devise_error_messages!.each do |key, value| %>
<% if key != saved_key %>
<div class="flash <%= key %>"><%= key %> <%= value %></div>
<% end %>
<% saved_key = key %>
<% end %>
<% end %>
I know it's been a while since this question was posted, but I think that it will help lot's of devise users :).
Big Edit:
As I love to extend my code, making it cleaner and share it with others, I recently wanted to change the devise_error_messages! method in order to use it in my views and make it display the trick I explained above.
So, here is my method:
def devise_error_messages!
html = ""
return html if resource.errors.empty?
errors_number = 0
html << "<ul class=\"#{resource_name}_errors_list\">"
saved_key = ""
resource.errors.each do |key, value|
if key != saved_key
html << "<li class=\"#{key} error\"> This #{key} #{value} </li>"
errors_number += 1
end
saved_key = key
end
unsolved_errors = pluralize(errors_number, "unsolved error")
html = "<h2 class=\"#{resource_name}_errors_title\"> You have #{unsolved_errors} </h2>" + html
html << "</ul>"
return html.html_safe
end
No big deal here, I reused the code I wrote in my view to show only one error pey attribute, because often the first one is the only relevant (like when the user forgets one required field).
I'm counting those "unique" errors and I'm making a H2 HTML title using pluralize and putting it BEFORE the errors list.
So now, I can use the "devise_error_messages!" as the default one and it renders exactly what I was already rendering before.
If you want to access a specific error message in your view, I now recommend to use directly "resource.errors[:attribute].first" or whatever.
Seya,
Kulgar.