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.
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
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
Thats it! Enjoy!!!