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!!!

Leave a comment

The & thing – Ruby Tidbits

Download video

Leave a comment

Using Statistics to improve Ruby speed

There is this big debate that Ruby is slow, yet no one wants to give up on Ruby. This language is so easy to program, that most people fall in love with it. I did fall in love with Ruby, and even wrote a book so that people can wet their hands in Ruby. You can get it here https://cloud.openmailbox.org/index.php/s/u4sX065QRgjbJL2/download

In this blog I will present a strange idea I have. The purpose of this blog  is to get this idea shot down or to kindle a debate in Ruby community.

Lets say we have a function in Ruby as shown

def foo object
# .....
end

This function must be converted to byte code somewhere. To this function foo we pass an object. It would be great for the compiler to know what kind of object it is so that things can be optimized. But its not such a great programming experience to specify the type of object. Remeber we are the masters and computers must understand us.

So lets say that this function gets called. Ruby runtime builds a table as shown below. If you note that type of object is A 85% of the time

Type of object:

Type A - 85%
Type B - 10%
Others - 5%

So Ruby run time in the long run, develops three different byte codes for the function foo. Each time when its called, it checks the type of object being passed and loads that particular byte code in memory.

I reckon this approach might slow down Ruby program interpretation a bit during initial stages, but as the interpreter learns about the program using statistics, things could run faster in future. Possibly we could bring in machine learning to know about frequently run programs and speed them up.

9 Comments

Poodr not so good

Karthikeyan Blogs

Poodr (Practical Object Oriented Design in Ruby) written by Sandi Menz is not so good at all. Wonder why so  many Ruby people recommended it to me. I wonder what the book can be used instead of paper weight, and it costs so much.

Any college student who has done mini to mega projects in his or her college would have surely discovered best techniques in software development and would have learned it implicitly. Sandi just stitched some blog posts perhaps written by some college people and has put it as a book.

Its also funny to know westerners have come up with name for every type of coding technique conceivable or something. It would be dangerous if bosses of code houses read the book, they would be pesting their workers to follow these type of coding techniques. Even if the workers followed and if they don’t know the techniques…

View original post 21 more words

Leave a comment

Whats new in Rails 5

Leave a comment

Named seeds in Rails

Sometimes rake db:seeds is not enough, you need something fine grained, like rake db:populate_companies , in order to achieve that I use this solution

Put this code in your rails application

Then in db/seeds/ you can write a seed file named populate_companies.rb , and thats in. Now from your terminal give rake db:seed:populate_companies and the file would be run as rake task.

Leave a comment

Matz watched a Tamil (Rajinikanth) Movie

Leave a comment