Search code examples
ruby-on-railsrubyomniauth

Rails - redirect user back to the original action after a signin before_action


I have a jobs model and a link to create a new job. I would like to force a user to sign in before visiting the new job form. I have set up a before_action that forces sign in.

application_controller.rb

  helper_method :current_user
  helper_method :require_signin!

  def current_user
     @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end

  def require_signin!
    if current_user.nil?
      redirect_to signin_path
    end
  end

jobs_controller.rb

before_action :require_signin!, only: [:new]

routes.rb

get '/auth/twitter' => 'sessions#new', :as => :signin

sessions_controller.rb

class SessionsController < ApplicationController
  def create
    auth = request.env["omniauth.auth"]
    user = User.from_omniauth(auth)
    session[:user_id] = user.id
    redirect_to user, :notice => "Signed in!"
  end
end

Current behavior When a user, who is not signed in, clicks the 'jobs/new' link, the chain of events is jobs#new -> login -> user (default redirect after signing in). User then must navigate back to jobs#new

Desired behavior When a user, who is not signed in, clicks the 'jobs/new' link, the chain of events is jobs#new -> login -> jobs#new.

I know the before_action is intercepting the original action, but I would like to complete the original action after signing in. Help?


Solution

  • To implement this, you can save the original route in session before redirecting to sign_in route, like:

    class JobsController
      before_action :save_original_path, only: [:new]
      before_action :require_signin!, only: [:new]
    
      private
    
      def save_original_path
        session[:return_to] = new_job_path
      end
    end
    

    and

    class SessionsController
      def create
        ...
        redirect_to (session[:return_to] || user), :notice => "Signed in!"
      end
    end