Devise: Redirect to sign up page instead of sign i

2019-08-14 22:28发布

问题:

If no user present, I want a request to be redirected to Sign Up page instead of Login page. So for that, I am overriding the authenticate_user! the method in Application controller:

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :authenticate_user!

  protected

  def authenticate_user!
    redirect_to new_user_registration_path unless User.any?
  end
end

Here, the issue is the page isn't redirected properly. The request is getting redirected to the sign-up page but indefinitely, i.e. request is not getting completed. On the rails server console it is showing:

Filter chain halted as :authenticate_user! rendered or redirected
Completed 302 Found in 0ms (ActiveRecord: 0.0ms)

回答1:

Work as well for me, I have fixed for me and my existing projects.

On the application_controller.rb run for every request and after overwriting authenticate_user! and after callback before_action :authenticate_user! all over the controller calling this method also from SessionsController and RegistrationsController when not signed_in, if you use that on separate controller then everything is ok like if you use this for home_controller.rb then when requesting for home_controller.rb without sign_in then he will refer to sign_up page.

After many searching, I have fixed that like below.

On the application.rb I have blocked I mean skipped before_filter devise controllers which is work for login, logout and signup like this

config.to_prepare do
  Devise::SessionsController.skip_before_action :authenticate_user!
  Devise::RegistrationsController.skip_before_action :authenticate_user!
end

and the application_controller.rb

before_action :authenticate_user!

protected
def authenticate_user!
    redirect_to new_user_registration_path, notice: 'Your custom message here' unless user_signed_in?
end

That's it!

Note

After this everything works properly but devise default edit and updates not work.

For this, you have to apply solution 2

Solution 2

devise default edit and updates will work if you remove this ! from authenticate_user

like below on the application.rb

config.to_prepare do
  Devise::SessionsController.skip_before_action :authenticate_user
  Devise::RegistrationsController.skip_before_action :authenticate_user
end

and the application_controller.rb

before_action :authenticate_user

protected
def authenticate_user
    redirect_to new_user_registration_path, notice: 'Your custom message here' unless user_signed_in?
end

If you apply this, make sure restart the server after edit application.rb file

Hope it helps



回答2:

Devise does not recommend overriding the authenticate_user and authenticate_user! methods.

Instead, define a custom failure app with a route method that returns a symbol representing the named route to redirect to:

# app/lib/my_failure_app.rb
class MyFailureApp < Devise::FailureApp
  def route(scope)
    :new_user_registration_url
  end
end

Then inside the Devise initializer, specify your failure app:

# config/initializers/devise.rb
config.warden do |manager|
  manager.failure_app = MyFailureApp
end

If you’re getting an uninitialized constant CustomFailure error, and you’ve put the CustomFailure class under your /lib directory, make sure to autoload your lib files in your application.rb file, like below

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

See https://github.com/plataformatec/devise/wiki/Redirect-to-new-registration-(sign-up)-path-if-unauthenticated