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.
来源:https://stackoverflow.com/questions/5903589/how-to-pass-through-parameters-during-devise-login