Devise便利ですよね。簡単にリッチな認証機能がつくれます。
# config/routes.rb devise_for :users
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
user_confirmation POST /users/confirmation(.:format) devise/confirmations#create
new_user_confirmation GET /users/confirmation/new(.:format) devise/confirmations#new
GET /users/confirmation(.:format) devise/confirmations#show
いまいちなところ
Devise::RegistrationsControllerの役割があいまい
/usersが Devise::RegistrationsController に取られてるのはひどい。普通 UsersController になるはずでしょう。
(PUT /usersやDELETE /usersも地味にひどい)
さらにここによく使うresources :usersを足すとカオスに…。
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy何をどう使えばいいんでしょうか、これ…。
何が問題なのか
- 複数形である
usersは普通「ユーザー全体」をさすはず(コレクションリソース)。なのに registrations#update は「自分自身を更新」つまり「自分自身」をさしている。 #cancel, #edit, #destroy も同様 - そもそもURLにも出てこない“registrations”っていったい何?
「自分自身」をさすリソースは1つしかないので単数形で表現できます。
resource :user # (a)単数 resources :users # (b)複数 resource :users # (c)まぎらわしいのでよくない
(a)と(b)は別のリソースなので区別しましょう。
解決策(案)
devise-better_routes gemを使うと、ルーティングはこのようになります。
# Gemfile gem 'devise-better_routes'
users POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
cancel_current_user GET /current_user/cancel(.:format) current_users#cancel
edit_current_user GET /current_user/edit(.:format) current_users#edit
current_user PATCH /current_user(.:format) current_users#update
PUT /current_user(.:format) current_users#update
DELETE /current_user(.:format) current_users#destroy謎のregistrationsは消えて、コントローラがusersとcurrent_usersに整理されました。
このコントローラは用意されていませんが、基本は単にこんな感じで作ってやればOKです。
# app/controllers/users_controller.rb class UsersController < Devise::RegistrationsController end # app/controllers/current_users_controller.rb class CurrentUsersController < Devise::RegistrationsController end
同様に、passwordとsessionもパスが変更されます。
オプション
/current_userって名前はいまいち…、というときは、オプションで変更することができます。
# config/routes.rb devise_for :users, path_names: {current_user: 'me'}
users POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
cancel_me GET /me/cancel(.:format) me#cancel
edit_me GET /me/edit(.:format) me#edit
me PATCH /me(.:format) me#update
PUT /me(.:format) me#update
DELETE /me(.:format) me#destroyいい感じじゃないですか?
Deviseへissueを投げてみた
Thanks for the proposal. Yes, it make sense, even though we have originally decided to not pollute two namespaces for the same Devise controller. Unfortunately, this is a very backwards incompatible change, so any change of this dimension would have to wait until Devise 4.0 (and we just released 3.0). Fortunately, you can customize it on your own, as you did. :)
So I am closing this but leaving a note to myself that we could possibly revisit this (in a year or two).
Registration routes are confusing · Issue #2505 · plataformatec/devise · GitHub
ってことで、リップサービスかもしれないけどDevise 4.0に期待w