WhyAyala WhyAyala - 1 month ago 7
Ruby Question

Why is devise not displaying authentication errors on sign in page?

I'm using rails 4.2

I have a helper file called devise_helper.rb

module DeviseHelper
def devise_error_messages!
return "" if resource.errors.empty?

messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
sentence = I18n.t("errors.messages.not_saved",
count: resource.errors.count,
resource: resource.class.model_name.human.downcase)

html = <<-HTML
<div class="row">
<div class="large-12 columns">
<div data-alert class="alert-box alert radius">
<h4>#{sentence}</h4>
<ul>#{messages}</ul>
</div>
</div>
</div>
HTML
html.html_safe
end
end


to customize error messages and it's working for registrations and passwords pages, but not for sessions pages. Why is this? I know that I can add something like this:

<div class="row">
<% if notice %>
<div data-alert class="alert-box info radius">
<%= notice %><%= link_to "X", '#', :class => 'close' %>
</div>
<% end %>
<% if alert %>
<div data-alert class="alert-box alert radius">
<%= alert %><%= link_to "X", '#', :class => 'close' %>
</div>
<% end %>
</div>


To my application.html.erb file and error messages will display there, but I don't understand why I have to add that when I have the devise helper already.
For the passwords and registrations, I just had to add <%= devise_error_messages! %> but the sessions pages don't seem to work that way. I'm not sure if this is just how devise works or if there's something I'm missing.

EDIT:
I generated the sessions controller but I never changed anything in it since generating it. From what I understand, devise will just use its default controller until I change the one i generated. My passwords controller is like this as well. I did make some changes to the registrations controller to configure permitted parameters.

class Users::SessionsController < Devise::SessionsController

end

Answer

Ouch, I tried on my own application, and it would seem that a login with blank/wrong fields DOES NOT generate errors on the model !

if you debug with byebug (in the first line of your view for example), you'll notice

resource.errors.count # => 0
flash # => ....@flashes={"alert"=>"Invalid email or password."}

Only explanation I can come up with, is that there exist a pre-verification of user input, which will add the error message "Invalid email or password." in your flash, and skip model validation.

However, devise_error_messages! does only show the errors contain in resource.errors

Probably, devise devs had a reason to do so. I will edit/comment this post if I can find a good explanation

WORKAROUND :

Actually, you could just explicitely run the validations :

at the beginning of devise_error_messages!

resource.validate # It will generate errors and populate `resource.errors`

I believe it shouldn't mess up with other actions that already work well (register, etc.)