webプロダクトいんふぉ

webの気になった情報を発信中!!

Deviseのルーティング制御方法

Railsでログイン機能をつける時にはDeviseを使う時が多いと思いますが、アプリケーションによっては、新規登録はサービス管理者側で行い、誰でも会員登録ができる状態を避けたい状況もあると思います。 そこで、今回はDeviseを使用して、サービスのview側ではログインしかできない状態を作っていきます。

Deviesの初期設定は下記のようになっています。

|Prefix  |Verb  |URI Pattern  |Controller#Action  |
|---|---|---|---|
|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  |
|new_user_password  |GET  |/users/password/new(.:format)  |devise/passwords#new  |
|edit_user_password  |GET  |/users/password/edit(.:format)   |devise/passwords#edit  |
|user_password  |PATCH  |/users/password(.:format)  |devise/passwords#update  |
|user_password  |PUT  |/users/password(.:format)  |devise/passwords#update  |
|user_password  |POST  |/users/password(.:format)  |devise/passwords#create  |
|cancel_user_registration  |GET  |/users/cancel(.:format)  |devise/registrations#cancel  |
|new_user_registration  |GET  |/users/sign_up(.:format)  |devise/registrations#new  |
|edit_user_registration  |GET  |/users/edit(.:format)  |devise/registrations#edit  |
|user_registration  |PATCH  |/users(.:format)  |devise/registrations#update  |
|user_registration  |PUT  |/users(.:format)  |devise/registrations#update  |
|user_registration  |DELETE  |/users(.:format)  |devise/registrations#destroy  |
|user_registration  |POST  |/users(.:format)  |devise/registrations#create  |

これをログインに必要な情報だけ残すようにします。

|Prefix  |Verb  |URI Pattern  |Controller#Action  |
|---|---|---|---|
|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  |

それにはroutes.rbを編集していきます。

変更前

devise_for :users

変更後

devise_scope :user do
  get '/users/sign_in' => 'devise/sessions#new', as: :new_user_session
  post '/users/sign_in' => 'devise/sessions#create', as: :user_session
  delete '/users/sign_out' => 'devise/sessions#destroy', as: :destroy_user_session
end

この部分で、Deviseのマッピングを行い、skipしてルーティングの設定は行わないようにしています。 devise_for :users, skip: :all

do以下で必要なルーティングだけ記述してあげれば完成です。

一点注意が必要になります。おそらくログアウト時にルーティングエラーが出ると思います。 これは、本来Deleteメソッドで呼ぶはずが、Getメソッドで呼んでしまっているのが原因です。 そこで、ログアウトのリンクを変更してあげます。具体的にはlink_toからbutton_toに変更する必要があります。

変更前

<%= link_to "ログアウト", destroy_user_session_path, method: :delete %>

変更後

<%= button_to "ログアウト", destroy_user_session_path, method: :delete, class: "nav-link waves-effect" %>