Reputation: 22150
I'm really missing something here.
I have read many things about devise redirects (seems like it is hard to implement for most people ...) but in my case I really don't get it.
Sometimes I read that the methods after_<action>_path_for(resource)
should be in the ApplicationController
, sometimes it is mentionned to be in a specific controller, overriding the devise one.
I'd rather have them in my ApplicationController
since it bothers me to create more Controllers just for a redirect, but if it is not possible at the end, I won't insist...
Here's the deal:
I have in my ApplicationController
: (and some others, but that's enough for the example)
def after_update_path_for(user)
flash[:notice] = 'Successfully updated password'
edit_user_path(user)
end
def after_inactive_sign_up_path_for(user)
flash[:notice] = 'Welcome! Please follow the steps!'
me_new_path
end
def after_sign_up_path_for(user)
flash[:notice] = 'Welcome! Please follow the steps!'
me_new_path
end
def after_sign_in_path_for(user)
if user.sign_in_count == 1
me_new_path
else
root_path
end
end
And the crazy thing, is that after_sign_in_path_for
is called, but not the other ones. Like when the user signs up it's the if user.sign_in_count == 1
that redirects him, not the after_inactive_sign_up_path_for
nor the after_sign_up_path_for
How come?
It could be related to my routes, so here's my routes.rb
extract:
devise_for :user, :skip => [:sessions, :registrations], :path => ''
devise_scope :user do
get :register, :to => 'devise/registrations#new'
post :register, :to => 'devise/registrations#create'
put :update_password, :to => 'devise/my_registrations#update'
get :login, :to => 'devise/sessions#new'
get :login, :to => 'devise/sessions#new', :as => :new_copasser_session
post :login, :to => 'devise/sessions#create'
delete :logout, :to => 'devise/sessions#destroy'
end
And I'm using Devise 3.1.0 with Ruby 1.9.3 and Rails 3.2.13
Thanks for the help!
EDIT
Thanks @rich-peck for your answer. I updated my routes.rb
this way :
devise_for :users, :path => '', :path_names => {
:sign_in => :login,
:registration => :register,
:sign_up => '',
:sign_out => :logout
}
which gives me the same routes as the previous ones (except I can't use login_path
helper anymore but it's not a big deal), but I still get the same results concerning redirects.
Here is the result of rake routes
:
new_user_session GET /login(.:format) devise/sessions#new
user_session POST /login(.:format) devise/sessions#create
destroy_user_session DELETE /logout(.:format) devise/sessions#destroy
user_password POST /password(.:format) devise/passwords#create
new_user_password GET /password/new(.:format) devise/passwords#new
edit_user_password GET /password/edit(.:format) devise/passwords#edit
PUT /password(.:format) devise/passwords#update
cancel_user_registration GET /register/cancel(.:format) devise/registrations#cancel
user_registration POST /register(.:format) devise/registrations#create
new_user_registration GET /register(.:format) devise/registrations#new
edit_user_registration GET /register/edit(.:format) devise/registrations#edit
PUT /register(.:format) devise/registrations#update
DELETE /register(.:format) devise/registrations#destroy
user_confirmation POST /confirmation(.:format) devise/confirmations#create
new_user_confirmation GET /confirmation/new(.:format) devise/confirmations#new
GET /confirmation(.:format) devise/confirmations#show
Any idea?
Upvotes: 0
Views: 4031
Reputation: 22150
So thanks to @rich-peck's help, we figured it out.
The question was why do after_sign_in_path_for
behave differently than after_sign_up_path_for
and cie ?
It appears, in the devise sources, that after_sign_in_path_for
is defined in a helper, whereas the other ones are methods of their controller (eg. Devise::RegistrationsController < DeviseController
)
Hence for after_sign_in_path_for
it works overriding in the ApplicationController
, whereas for the other ones, it is necessary to create a registrations_controller.rb
file, to override the method in it:
class RegistrationsController < Devise::RegistrationsController
protected
def after_sign_up_path_for(copasser)
flash[:notice] = 'Welcome! Please follow the steps!'
me_new_path
end
end
and to set the router.rb
this way:
devise_for :copassers, :controllers => {
:registrations => :registrations
}
I suppose the behaviour is different because :registerable, :recoverable
etc. are modules of devise, not necessarily used, and the helper wouldn't be appropriate in that case. A devise contributor could help us on this point.
Upvotes: 1
Reputation: 76774
Devise relies heavily on a central variable called "resource". This variable defines how devise operates on your system, and is why you have to "attach" Devise to :users or similar
People get problems with Devise because they don't follow the conventions, and put their forms everywhere. If they read the Devise readme, they'd appreciate that it's quite flexible :)
I believe your problem is to do with your routes, in that you might want to consolidate all those static routes into something like this:
devise_for :users, :path => '', :controllers => {:sessions => 'sessions', :registrations => 'registrations'}, :path_names => { :sign_in => 'login', :password => 'forgot', :confirmation => 'confirm', :unlock => 'unblock', :registration => 'register', :sign_up => 'new', :sign_out => 'logout'}
Upvotes: 1