Devise is giving me a pretty hard time. For now, everything else seems to be working, except the sign up redirect. I want devise to redirect to my town controller at index action, upon sign up or login (login actually works).
I've tried overriding RegistrationsController and i've tried adding an applicationsController function like :
def after_sign_in_path_for(resource_or_scope)
if resource_or_scope.is_a?(User)
town_path
else
super
end
end
Still, i'm getting the same error :
NoMethodError in User/townController#index
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.*
Seriously, i cannot find a way to do it. Any ideas please ? :)
EDIT : MY ROUTES
new_user_session GET /users/sign_in(.:format) {:action=>"new", :controller=>"devise/sessions"}
user_session POST /users/sign_in(.:format) {:action=>"create", :controller=>"devise/sessions"}
destroy_user_session GET /users/sign_out(.:format) {:action=>"destroy", :controller=>"devise/sessions"}
user_password POST /users/password(.:format) {:action=>"create", :controller=>"devise/passwords"}
new_user_password GET /users/password/new(.:format) {:action=>"new", :controller=>"devise/passwords"}
edit_user_password GET /users/password/edit(.:format) {:action=>"edit", :controller=>"devise/passwords"}
PUT /users/password(.:format) {:action=>"update", :controller=>"devise/passwords"}
user_registration POST /users(.:format) {:action=>"create", :controller=>"devise/registrations"}
new_user_registration GET /users/sign_up(.:format) {:action=>"new", :controller=>"devise/registrations"}
edit_user_registration GET /users/edit(.:format) {:action=>"edit", :controller=>"devise/registrations"}
PUT /users(.:format) {:action=>"update", :controller=>"devise/registrations"}
DELETE /users(.:format) {:action=>"destroy", :controller=>"devise/registrations"}
root /(.:format) {:action=>"index", :controller=>"home"}
user_root /user(.:format) {:action=>"index", :controller=>"user/town"}
home /home(.:format) {:action=>"index", :controller=>"home"}
town /town(.:format) {:action=>"index", :controller=>"town"}
inbox /messages(.:format) {:action=>"index", :controller=>"messages"}
inbox /messages/inbox(.:format) {:action=>"inbox", :controller=>"messages"}
Routes.rb :
devise_for :users
root :to => "home#index"
namespace :user do
root :to => "town#index"
end
scope :path => '/hom开发者_如何学JAVAe', :controller => :home do
match '/' => :index, :as => 'home'
end
scope :path => '/town', :controller => :town do
match '/' => :index, :as => 'town'
end
......
Im using Devise 1.3.4 with Ruby On Rails 3.0.7. After checking out the internet for a solution, what i did was simply pasting the following code
*first)*To redirect after a succesful sign up to the welcome page,place in /config/routes.rb the following (note, replace :user
with the argument you provided to devise_for
):
namespace :user do
root :to => "welcome#index"
end
*second)*To redirect after a sign out (to the welcome page also), place in the /app/controllers/application_controller.rb this method:
private
# Overwriting the sign_out redirect path method
def after_sign_out_path_for(resource_or_scope)
welcome_index_path
end
This worked for me, i hope it does for all of you.
An answer to this question that worked perfectly for me is explained on the Devise Wiki here:
How To: Redirect to a specific page on successful sign up (registration)
This is how I got this working.
# In your routes.rb
match 'dashboard' => 'user_dashboard#index', :as => 'user_root'
Then make sure you don't have a before_filter :authenticate_user!
set on your home#index
controller.
Since no one is answering I'll chime in. Are you sure this is the code that's causing the error? Your resource_or_scope
being nil makes it seem like Devise is the problem but I doubt that's the case. So I think the problem is somewhere else.
I'd try the following just to make sure it works first.
def after_sign_in_path_for(resource)
"http://www.google.com"
end
If that does work then try checking the resource
variable to make sure it's not nil.
What Tony said. Namespace is not meant to be used this way. I don't know who came up with this hack that doesn't work at all, but unfortunately, it's one of the very first solutions that come up when googling.
namespace :user do
root :to => "town#index"
end
sets '/user' as the user_root_path and points to the index action of 'user/town' controller which you don't have. What you have is 'town' controller. And that's why you got the error. What you need is
get '/town', to: 'town#index', as: 'user_root'
This way, '/town' points to 'town#index' and is set up as your user_root_path, which is what Devise redirects to after user
- sign in
- sign up
- update password
so you do not even need to override after_sign_in_path_for
, which, contrary to what many believe, is not the best place to tackle the devise redirect problem.
on Rails 4.1+ and Devise 3.2
Did you tried overwriting devise sign_in_and_redirect
method; It will work for you
def sign_in_and_redirect(resource_or_scope,resource)
if resource_or_scope == :user
redirect_to town_path
else
super
end
end
Not sure if this is helpful or not but I ran into the same problems above but difference is I'm using a custom registrations controller.
From the devise source code for RegistrationsController it appears it is calling sign_in_and_redirect which in turns passes it to redirect_location method.
I override the redirect_location to just return the path from after_sign_up_path_for(resource) rather than stored_location_for(scope) || after_sign_up_path_for(resource).
Within after_sign_up_path_for(resource), I customise the method to redirect to the right path based on the type of user
Works in Rails 3.0.5 and Devise 1.3.0 for me.
The issue is that Devise bypasses after_sign_in_path_for(resource)
when signing into a resource that has just been created. What you need is after_sign_up_path_for(resource)
:
# override in your ApplicationController or custom Devise::RegistrationsController
def after_sign_up_path_for(resource)
if resource.is_a?(User)
town_path
else
super
end
end
You'll still need your after_sign_in_path_for(resource)
override to correctly redirect subsequent sign ins to the resource.
I had a similar problem. Eventually resorted to if statement in application controller. If user signed in and they do not have a profile then route to the new_profile_path
Just to add on to the other great input; one thing you may overlook, in case you are using the confirmable
attribute with your models, is that inactive accounts use a different method if you want to alter the after_sign_up_path
, as documented on the devise wiki: https://github.com/heartcombo/devise/wiki/How-To:-Redirect-to-a-specific-page-on-successful-sign-up-%28registration%29.
In this case, use:
class RegistrationsController < Devise::RegistrationsController
protected
def after_inactive_sign_up_path_for(resource)
'/an/example/path'
end
end
精彩评论