例えば User モデルで devise を設定したとき、ログイン用のパスは /users/sign_in
、ログアウトは /users/sign_out
になります。個人的には /login
/logout
の方が好みなのでroutes.rb
を下記のようにしました。
devise_for :users, skip: [:sessions]
devise_scope :user do
get 'login' => 'devise/sessions#new'
post 'login' => 'devise/sessions#create'
get 'logout' => 'devise/sessions#destroy'
end
1行目の devise_for :users, skip: [:sessions]
でデフォルトのログイン関連のパスを削除して、その後で /login
/logout
のパスの設定を入れています。これでばっちりですね!
…と思いきや、思わぬ落とし穴がありました。パスワードリセットをした後に遷移するパスを生成するところでエラーが発生するのです。該当部分のソースを見てみると、下記のようになっています。
class Devise::PasswordsController < DeviseController
# ...
# The path used after sending reset password instructions
def after_sending_reset_password_instructions_path_for(resource_name)
new_session_path(resource_name) if is_navigational_format?
end
# ...
end
new_session_path(resource_name)
は User モデルで devise を使っているときは new_user_session_path
を返します。しかし routes.rb で devise_for :users, skip: [:sessions]
としてデフォルトのログイン関連のパスを削除しているためにエラーになってしまいます。
devise は、ログイン後に遷移するパスは ApplicationController#after_sign_in_path_for
を定義すれば設定を変更できるようになっています。ただ、「パスワードリセットをした後に遷移するパス」については対応していないようです。
対処法
結局
config/initializers/
配下にファイルを作り、その中でDevise::PasswordsController#after_sending_reset_password_instructions_path_for
をオーバライドするconfig/routes.rb
でdevise_for :users, skip: [:sessions]
の skip オプションを削除する- ただ、そうすると
/users/sign_in
と/login
が混在してしまう
- ただ、そうすると
のどちらかしかなさそうです。どっちも微妙ですね…。deviseさん…
追記
エントリ公開後にコメントいただきました!@deeeki さんありがとうございます!
@netwillnet rake routes で確認したのみですが、devise_for の :path_names オプションを使うとオーバーライドしなくてもよさそうですー https://t.co/EapIOpWLAV
— でーき (@deeeki) July 2, 2013
ということで調べてみました。
devise_for :users, :path => '', :path_names => {:sign_in => 'login', :sign_out => 'logout'}
のようにすると、確かに /login
と /logout
ができます。ただ
- named routes が
new_user_session_path
になってしまう (login_path
が理想) :path => ''
としているため、他の/users
配下のパスも影響を受ける- 例:
/users/confirmation
→/confirmation
- 例:
なので、これでバッチリ!とはいきませんでした。ざんねん><
named routes を妥協できるなら下記のように書くのが一番よさそうです。
devise_for :users, skip: [:sessions]
devise_scope :user do
get 'login' => 'devise/sessions#new', as: :new_user_session
post 'login' => 'devise/sessions#create', as: :user_session
get 'logout' => 'devise/sessions#destroy', as: :destroy_user_session
end