Redirect User to Signup

2019-03-15 09:27发布

问题:

Using before_action :authenticate_user! to check if user logged in. But it sends users to login instead of signup.

Tried different ways of directing user to signup instead of login, but they do not send the user back to the original page after successful signup.

How can I send a user to signup and direct a user back to the original page afterwards?

Attempts:

before_filter :auth_user

def auth_user
  redirect_to new_user_registration_url unless user_signed_in?
end

Routes File

Rails.application.routes.draw do
  devise_for :installs
  resources :orders
  resources :products
  devise_for :users

  get 'dashboard' => 'pages#dashboard'
  get 'contact' => 'pages#contact'
  get 'cart' => 'carts#index'

  root 'pages#home'

回答1:

What you are looking for is a referer. Having your before_filter working, you can override the Devise's after_sign_up_path_for:

def after_sign_up_path_for(user)
  request.referer
end

EDIT

Since request.referer is somehow not working, I think you could go with a session-based solution:

def auth_user
  session[:before_sign_up_path] = request.fullpath
  redirect_to new_user_registration_url unless user_signed_in?
end

def after_sign_up_path_for(user)
  session[:before_sign_up_path]
end


回答2:

Devise uses warden for authentication. Thus to override the whole behavior you have to override the way devise asks it to handle authentication failures.

Create a class that extends Devise::FailureApp

class RedirectToSignUp < Devise::FailureApp
  def redirect_url
     new_user_registration_url
  end

  def respond
    if http_auth?
      http_auth
    else
      redirect_to new_user_registration_url
    end
  end
end

Add this to your devise initializer config/initializers/devise.rb

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

I believe this will solve your problem and will redirect you to the page you were at since you are overriding only the redirect route.



回答3:

I haven't tried it but this seems to be what you are looking for. Note that it says that it is out of date. So you should see the source code if you want to understand what's going on.

Navigating through the source code of Devise(this and this) my guess is that you can extend Devise::RegistrationsController and then override the method after_sign_up_path_for to be stored_location_for(:user) || root_path.



回答4:

the way I like to set up my users area using devise is:

  # config/routes.rb
  devise_for :users, :controllers => {
    registrations: 'users/registrations',
    sessions: "users/sessions",
    passwords: 'users/passwords',
    confirmations: 'users/confirmations'
  }

  authenticate :provider do
    namespace :providers do
      ....
    end
  end

Then I have a controller that manages all other users controllers like this

#app/controllers/user_controller.rb
class UserController < ApplicationController
  before_filter :authenticate_user!
  layout 'users/default'
  before_filter :check_user_active

  private
  def check_user_active
    unless current_user.active
      flash[:notice]= t(:user_not_active)
      sign_out current_user
      redirect_to new_user_session_path
    end
  end
end

all my other user controllers look inherit from it like

#app/controllers/users/users_controller.rb
class Users::UsersController < UserController
  ...
end

I hope that this helps.



回答5:

This is very simple

User store_location_for method

Like

before_filter :auth_user

def auth_user
  unless user_signed_in?
    store_location_for(:user, request.fullpath)
    redirect_to new_user_registration_url 
  end
end