I have a page whose path is (e.g.) /premises/92 on which I\'m displaying \"please [log in] or [register] for additional information\" if the user is not logged in, and I wan
I do like this:
class ApplicationController < AC::Base
after_filter :clear_attached_unit # UPDATED
protected
def clear_attached_unit
session[:attached_unit_path] = nil unless keep_attached_unit_path?
end
def keep_attached_unit_path? # UPDATED
@keep_attached_unit_path
end
end
class UnitController < ApplicationController
before_filter :attach_unit, :only => [:show]
protected
def attach_unit
session[:attached_unit_path] = request.url if request.get? && !request.xhr?
end
end
class SessionsController < Devise::SessionsController
before_filter :keep_attached_unit_path! # UPDATED
protected
def keep_attached_unit_path! # UPDATED
@keep_attached_unit_path = true
end
def after_sign_in_path_for(resource_or_scope)
if resource_or_scope.is_a?(User) && session[:attached_unit_path].present?
session[:attached_unit_path]
else
super
end
end
end
And extract this to module.
I found this whole devise redirect thing quite confusing.
Where @rorra says Devise uses session["#{scope}_return_to"]
, he means that Devise default after_sign_in_path_for(resource)
will use that variable through the method stored_location_for(resource)
.
So you should save the location you want to store in the variable session["#{scope}_return_to"]
, which will usually be session["user_return_to"]
. To do this place the following in your application_controller.rb:
after_action :store_location
def store_location
# store last url - this is needed for post-login redirect to whatever the user last visited.
if (request.fullpath != "/users/sign_in" &&
request.fullpath != "/users/sign_up" &&
request.fullpath != "/users/password" &&
request.fullpath != "/users/sign_out" &&
!request.xhr?) # don't store ajax calls
session["user_return_to"] = request.fullpath
end
end
In some cases you will not need to define an after_sign_in_path_for(resource)
method as devise's default method will do all the redirects for you and if their is no redirect url available you will be redirected to the resource root path (usually user root path) and if that doesn't exist you will be redirected to the root path. If however, you would like to customise where the user is sent if there is no redirect url available, add the following to your application_contorller.rb (and change root_path
accordingly):
def after_sign_in_path_for(resource)
stored_location_for(resource) || root_path
end
Devise
looks for the key "#{resource}_return_to"
in the session.
Here I am quoting the API:
By default, it first tries to find a valid
#{resource}_return_to
key in the session, then it fallbacks to#{resource}_root_path
, otherwise it uses theroot_path
.
Here is the link to the API
Devise use
session["#{scope}_return_to"]
So you can use session["user_return_to"]
if your model for authentication is User.
here's the best I could come up with. Works perfectly also with facebook authentication. by adding more restrictions to the prepending of urls to the session variable you can remove more and more paths you don't want the user to return too (e.g. callbacks, splash pages, landing pages, etc)
#ApplicationsController
after_filter :store_location
def store_location
session[:previous_urls] ||= []
# store unique urls only
session[:previous_urls].prepend request.fullpath if session[:previous_urls].first != request.fullpath && request.fullpath != "/user" && request.fullpath != "/user/login" && request.fullpath != "/" && request.fullpath != "/user/logout" && request.fullpath != "/user/join" && request.fullpath != "/user/auth/facebook/callback"
# For Rails < 3.2
# session[:previous_urls].unshift request.fullpath if session[:previous_urls].first != request.fullpath
session[:previous_urls].pop if session[:previous_urls].count > 3
end
def after_sign_in_path_for(resource)
@url = session[:previous_urls].reverse.first
if @url != nil
"http://www.google.com" + @url
else
root_path
end
end