简体   繁体   中英

Devise after_sign_in_path_for works, but not the other ones

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?

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.

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'}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM