How do I pass parameters during the Devise sign-in process?
I have a collection of users, each with their own profile page. I want them to be able to view their own profile page but none of the other users' profile pages, unless they're an admin in which case they have access to everything in the application.
I created a Users controller, and applied the following code开发者_运维问答 to the beginning of the controller. I replaced looking up by ID with their username, so /users/username
to access a profile:
filter_access_to :all do
current_user == User.find_by_username(params[:id]) or
has_role? :admin
end
And I specified in routes.rb:
root :to => "users#show"
When the user accessed http://appli.cat.ion
they would be prompted for login credentials, then be redirected to the root_path
which is the show action of the Users controller. Unless I can pass along the id
param during the sign-in process, this will result in an endless redirect loop. Is there something in Devise that helps with this problem?
I believe the following two Devise methods can help:
after_sign_in_path_for(resource)
and
stored_location_for(resource)
I've overriden after_sign_in_path
to the following:
def after_sign_in_path_for(resource)
user_root_path(:id => current_user.username)
end
which provides the desired effect: user logs in, gets redirected to their profile page, but only if I return nil
in stored_location_for
like:
def stored_location_for(resource)
nil
end
Again, my goal is to redirect a user to their profile page if having navigated to (http)://appli.cat.ion/
directly if they've signed-in. If a user navigates to (http)://appli.cat.tion/otherresources
then I want to sign the user in, then redirect them to the page they requested. If I return nil
in stored_location_for
then the user will ALWAYS get redirected to their profile page no matter what, which is undesirable at best, and unusable at worst. I think that if I navigate to the application sign-in directly then stored_location
would return nil
, and upon signing in be directed to my profile page, but it is just redirecting me to the root_path
.
I think you can create a profile action within the UsersController which does a redirect to the user show page, then mark it as user root.
In UsersController:
class UsersController < ApplicationController
...
def profile
redirect_to user_url(:id => current_user.username)
end
...
end
In routes:
resources :users do
get 'profile', :on => :collection, :as => :user_root
end
And don't need to use the after_sign_in_path
hook.
精彩评论