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

前端 未结 4 1279
花落未央
花落未央 2020-12-29 14:41

I\'m using rails 4.2

I have a helper file called devise_helper.rb

module DeviseHelper
    def devise_error_messages!
        return \"\" if resource         


        
相关标签:
4条回答
  • 2020-12-29 14:51

    When you ran devise:install (or something similar), it must have created views with some specific line of codes to display these messages.

    If you look at this link, they explain that you can add <%= devise_error_messages! %> in your views to display those error messages (which isn't really different from having a generic <% flash.each {...} %> somewhere in your HTML...)

    Most likely, the views related to sessions do not contain this line of code.

    0 讨论(0)
  • 2020-12-29 15:05

    For newer version of Rails/Devise I recommend:

    Instead of <%= devise_error_messages! %> do:

          <% if flash[:alert] %>
            <%= flash[:alert] %>
          <% end %>
    

    Your test may look something like this (note, you must make this a 'feature' functional test to have access to the "page" variable):

    RSpec.feature 'Sign In', :type => :feature do
    
      describe "correct error message w/ wrong password" do
        before :each do
          @user = create(:user)
          @user.confirm
    
          visit new_user_session_path
          fill_in "user_email", with: @user.email
          fill_in "user_password", with: "wrongpassword"
          click_button "Log in"
        end
    
        it "tells user on page 'Invalid Email or password'" do
          expect(page).to have_text("Invalid Email or password")
        end
      end
    
    end
    
    0 讨论(0)
  • 2020-12-29 15:10

    I like this way. The HTML part is kind of original though.

    I do not want to separate displaying error messages about authentication. So, I'm using this way.

    module DeviseHelper
      def devise_error_messages!
    
        flash_alerts = []
    
        if !flash.empty?
          flash_alerts.push(flash[:error]) if flash[:error]
          flash_alerts.push(flash[:alert]) if flash[:alert]
          flash_alerts.push(flash[:notice]) if flash[:notice]
          sentence = I18n.t("devise.failure.invalid") #=> "Invalid email or password."
        else
          sentence = I18n.t("errors.messages.not_saved",
                            count: resource.errors.count,
                            resource: resource.class.model_name.human.downcase)
        end
    
        return "" if resource.errors.empty? && flash_alerts.empty?
    
        errors = resource.errors.empty? ? flash_alerts : resource.errors.full_messages
        messages = errors.map { |msg| content_tag(:li, msg) }.join
    
        html = <<-HTML
        <div class="alert alert-danger">
          <div id="error_explanation">
            <strong>#{sentence}</strong>
            <ul class="m-b-0 p-l-30 ">#{messages}</ul>
          </div>
        </div>
        HTML
    
        html.html_safe
      end
    end
    
    0 讨论(0)
  • 2020-12-29 15:13

    A login with blank/wrong fields does not trigger (your) validations on the model, and therefore won't show your validation errors !

    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."}
    

    Devise populates the "alert flash" with specific sign in error messages unique to this context of sign-in.

    Why do you not see all model validation error messages ? Because that wouldn't make sense : suppose your model has a mandatory :gender attribute with validates_presence_of :gender. If normal model errors were added, then you would also see "gender cannot be blank" in the list of errors when your user tries to sign in with a wrong login :oops:.

    devise_error_messages! is a specific devise method meant to show those specific errors. You can think of it as a partial validation on the fields that are used for sign in (and that are defined in your devise config file)

    WORKAROUND :

    If you really want to show all your error messages, 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.)

    0 讨论(0)
提交回复
热议问题