Rails: deviseのURLをカスタムしたい

次のようにdeviseのURLをカスタムする方法です。

* /users/sign_in → /login
* /users/sign_out → /logout
* /users/password → /password
* /users/sign_up → /signup
* /users/edit → /user (アカウント編集)

# 変更前


```rb: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
                         PATCH  /users/password(.:format)      devise/passwords#update
                         PUT    /users/password(.:format)      devise/passwords#update
cancel_user_registration GET    /users/cancel(.:format)        devise_invitable/registrations#cancel
       user_registration POST   /users(.:format)               devise_invitable/registrations#create
   new_user_registration GET    /users/sign_up(.:format)       devise_invitable/registrations#new
  edit_user_registration GET    /users/edit(.:format)          devise_invitable/registrations#edit
                         PATCH  /users(.:format)               devise_invitable/registrations#update
                         PUT    /users(.:format)               devise_invitable/registrations#update
                         DELETE /users(.:format)               devise_invitable/registrations#destroy
```

# 変更後

```rb:config/routes.rb
  devise_scope :user do
    get 'login' => 'devise/sessions#new', as: :new_user_session
    post 'login' => 'devise/sessions#create', as: :user_session
    delete 'logout' => 'devise/sessions#destroy', as: :destroy_user_session
    get 'signup' => 'devise_invitable/registrations#new', as: :new_user_registration
    post 'signup' => 'devise_invitable/registrations#create', as: :user_registration
    get 'signup/cancel' => 'devise_invitable/registrations#cancel', as: :cancel_user_registration
    get 'user' => 'devise_invitable/registrations#edit', as: :edit_user_registration
    patch 'user' => 'devise_invitable/registrations#update', as: nil
    put 'user' => 'devise_invitable/registrations#update', as: :update_user_registration
    delete 'user' => 'devise_invitable/registrations#destroy', as: :destroy_user_registration
    get 'password' => 'devise/passwords#new', as: :new_user_password
    post 'password' => 'devise/passwords#create', as: :user_password
    get 'password/edit' => 'devise/passwords#edit', as: :edit_user_password
    patch 'password' => 'devise/passwords#update'
    put 'password' => 'devise/passwords#update', as: :update_user_password
  end
  resources :users
```

ルーティングは次のようになります:

```
         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
    new_user_registration GET    /signup(.:format)           devise_invitable/registrations#new
        user_registration POST   /signup(.:format)           devise_invitable/registrations#create
 cancel_user_registration GET    /signup/cancel(.:format)    devise_invitable/registrations#cancel
   edit_user_registration GET    /user(.:format)             devise_invitable/registrations#edit
                          PATCH  /user(.:format)             devise_invitable/registrations#update
 update_user_registration PUT    /user(.:format)             devise_invitable/registrations#update
destroy_user_registration DELETE /user(.:format)             devise_invitable/registrations#destroy
        new_user_password GET    /password(.:format)         devise/passwords#new
            user_password POST   /password(.:format)         devise/passwords#create
       edit_user_password GET    /password/edit(.:format)    devise/passwords#edit
                 password PATCH  /password(.:format)         devise/passwords#update
     update_user_password PUT    /password(.:format)         devise/passwords#update
```

あわせてビューで`<form>`の`action`を明示する必要があります。

```diff:app/views/devise/passwords/edit.html.slim
-    = form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put, role: "form" }) do |f|
+    = form_for(resource, :as => resource_name, :url => update_user_password_path, :html => { :method => :put, role: "form" }) do |f|
```


```diff:app/views/devise/passwords/new.html.slim
-    = form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post, role: "form" }) do |f|
+    = form_for(resource, :as => resource_name, :url => new_user_password_path, :html => { :method => :post, role: "form" }) do |f|
```


```diff:app/views/devise/registrations/edit.html.slim
-    = form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f|
+    = form_for(resource, :as => resource_name, :url => update_user_registration_path, :html => { :method => :put }) do |f|

...

-  = link_to t('.cancel_my_account', :default => "Cancel my account"), registration_path(resource_name), :data => { :confirm => t('.are_you_sure', :default => "Are you sure?") }, :method => :delete
+  = link_to t('.cancel_my_account', :default => "Cancel my account"), destroy_user_registration_path, :data => { :confirm => t('.are_you_sure', :default => "Are you sure?") }, :method => :delete
```