So you would like to build your own custom Rails authentication redirect back after authentication

I was in the same situation:

If you are like me,and Ryan Bates, you like doing the important things yourself.  If there are errors, they are your errors.
Chances are you will want to create your Rails authentication from scratch yourself. Ryan of Railscasts has an excellent screencast about this.

I switched from Devise to the  custom authentication using this screencast. It was a breeze.
So now comes the customisation. One of these is the all-important Rails authentication redirect back to the funnel a user came from after they are done signing in, or up.

This can actually be achieved very easily:

Force authentication

Force authentication

Say I have a CharitiesController, that I want to close to unauthenticated users. In line with Devise, I would do this to force them to authenticate:

class CharitiesController > ApplicationController
  before_filter :authenticate_user!, except: [:show, :index]

Set a return point

In my ApplicationController, given i have set the user sign in route to user_login, I can define a return point:

class ApplicationController > ActionController::Base
  def authenticate_user!(return_point = request.url)
    unless user_signed_in?
      set_return_point(return_point)
      redirect_to user_login_path
    end
  end
  
  def return_point
    session[:return_point] || root_path
  end
end

Redirect back using return point

In my UserSessionsController, I can redirect the user back to the return point:

class UserSessionsController > ApplicationController
  def create
    user = User.find_by_email(params[:email])
    if user && user.authenticate(params[:password])
      session[:user_id] = user.id
      redirect_to return_point, notice: "You are now signed in"
    end
  end
[...]

Now, whenever a controller calls authenticate_user!, my ApplicationController will save the calling URL before redirecting to the login page, and by fetching return_point from the UserSessionsController, I can redirect them back to that page. I can even override it, such that I can send them wherever I want, should I so desire. Awesome!

Update: As Roman suggests, I should add the set_return_point method. Here it is:

def set_return_point(path, overwrite = false)
  if overwrite or session[:return_point].blank?
    session[:return_point] = path
  end
end