Devise after_sign_in_path_for works, but not the other ones

此生再无相见时 提交于 2019-12-25 03:56:26

问题


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?


回答1:


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.




回答2:


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


来源:https://stackoverflow.com/questions/19451881/devise-after-sign-in-path-for-works-but-not-the-other-ones

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!