heroxav
heroxav

Reputation: 1467

Rails, Devise: DoubleRenderError in FailureApp

I am trying to configure Devise so that whenever a User which account has not been confirmed logs in, he gets redirected to the new_confirmation_path.
This is what I've got so far:

lib/custom_failure.rb

class CustomFailure < Devise::FailureApp
    def redirect_url
        if warden_message == :unconfirmed
            redirect_to new_user_confirmation_path(q: "unconfirmed")
        else
            super
        end
    end
    def respond
        if http_auth?
            http_auth
        else
            redirect
        end
    end
end

config/application.rb

config.autoload_paths << Rails.root.join('lib')

config/initializers/devise.rb

config.warden do |manager|
    manager.failure_app = CustomFailure
end

Unfortunately I get the following error, whenever a User tries to log in:

AbstractController::DoubleRenderError in Users::SessionsController#create

Render and/or redirect were called multiple times in this action. Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".

Error in lib/custom_failure.rb (around line #15)

I followed this Devise Wiki Page

Upvotes: 2

Views: 1105

Answers (1)

Wikiti
Wikiti

Reputation: 1636

As stated by the error, you are performing a double render (render or redirect). I guess that's it's directly related to your redirect_url method.

Looking on the devise's wiki, there's no need to perform a redirect while override the redirect_url method. Also, by checking devise's failure code, at the end of the failed request, your application is doing this:

redirect_to(redirect_url)
# Which is equal to
redirect_to(redirect_to(new_user_confirmation_path(q: "unconfirmed")))

Which is wrong. To fix it, specify only the url instead of a redirection in your redirect_url override:

class CustomFailure < Devise::FailureApp
  def redirect_url
    if warden_message == :unconfirmed
      # Remove the `redirect_to` call
      new_user_confirmation_path(q: "unconfirmed")
    else
     super
    end
  end

  # ...
end

Upvotes: 1

Related Questions