Redirecting Devise Users To Their Last Visited Page

It’s always a nice gesture to redirect your users to the page they were last visiting. Imagine a scenario where your app sends out mailers with a link to a page that requires a login to see. You can’t assume that your user would always be logged in, so when clicking on this, he/she would be redirected to the sign in page. They then sign in and… they’re back on the homepage. So they leave. Retention 0, distrust 1.

What should happen in this scenario is, the app should automatically redirect the user to the page he/she was supposed to look at before getting whisked away. There’s a lot of ways to do this, and a few ways even recommend persisting the user location to your database. YUCK.

Why would you want to make a database call for every page the user visits? What would happen when your app scales? Or what would happen when your user isn’t even in the system, where would you persist that data, so that when he does eventually sign up, you can provide a seamless transition? Persisting something as volatile as user location is not a good idea.

Enter session.

A session is defined as a series of related browser requests that come from the same client during a certain time period. — Google (Actually Oracle)

And guess what? The session remains the same for a user who is not logged in, to when they log in. Aaaand guess what else? You can persist data on your session!

Here’s what you can do to achieve this,

1. Persist user location to the session.

class ApplicationController < ActionController::Base
 protect_from_forgery with: :exception, prepend: true
before_action :persist_last_visited_path, :authenticate_user!,  except: [:home]
 def home
 end
def persist_last_visited_path
  unless Rails.configuration.ignored_paths.include?(request.path) || request.xhr?
   session[:last_visited_path] = request.path
  end
 end
end

Any location a user visits in your app, has to go through your ApplicationController. So it’s a good idea to add a single before_actionhere to persist it. I like to filter out the paths I persist, and those usually include Devise default paths. Since I don’t want my user to be in an endless loop after he signs up/in. (User signs up, session persists and he’s redirected back to sign up, not good!) Also, I block out XHR requests.

Add a list of ignored paths to your application.rb. You can even create an initializer for this.

# These paths will be ignored when redirecting the user to last visited page
# Devise routes need to always be here, so that a redirect loop does not occur
# after signing in
config.ignored_paths = %W(/users/sign_in /users/sign_up /users/password /users/sign_out /users/confirm_password)

2. Redirect the user if the session variable exists.

Add this to your ApplicationController too,

def after_sign_in_path_for(resource)
 if session[:last_visited_path].present?
  session[:last_visited_path]
 else
  root_path
 end
end

The after_sign_in_path_for method is automatically called by Devise once the user logs in. it’s a simple check to see if the session variable exists, redirect the user to his last location, or default to root_path.

Thats it! Enjoy!!!

Advertisements
  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: