【Rails】 Deviseを複数導入する場合

はじめに
---
deviseを導入すると、簡単に認証機能が実装できて本当に便利なgemですよね！
Ruby on Railsを学び始めて２ヶ月目の頃、ユーザーと管理者に分けてdevise機能を２つ実装したい、こういった時はどうしたら良いのか、また複数のdevise間で両者とも使用するモデルに関してはどうしたら良いのか、と少し悩んだことがありましたので、今回の記事のテーマに選定致しました。
<br>

前提
---
今回説明するモデルを以下の三点に絞らせて頂いております。
● devise User
● devise Admin
● 両者に共通してItemモデルを使用

<br>

開発環境
---
Ruby 2.6.3
Rails 5.2.4.4
<br>

gemを導入
---
```Gemfile.
gem 'devise'
```
```terminal.
$ bundle install
```
<br>

ユーザー用、管理者用のdevise機能実装
---
deviseを複数実装することは意外と簡単です！
User、Adminのように適宜名前を付け、各コマンドを実行すればモデル、ビュー、コントローラーは作成出来ます。


```terminal.
$ rails g devise:install

# ユーザー用のdevise作成
$ rails g devise User name:string 
$ rails db:migrate
$ rails g devise:views users
$ rails g devise:controllers users

# 管理者用のdevise作成
$ rails g devise Admin
$ rails db:migrate
$ rails g devise:views admins
$ rails g devise:controllers admins
```
<br>

model / controller
---
ここで少し頭を悩ませることになります。
ECサイトを例にあげると、Item(商品)モデルを必ず作成するかと思います。このItemモデルの働きをユーザーと管理者それぞれの立場で考えてみましょう。

● ユーザー
　(例)商品を閲覧する、商品の詳細画面へ飛ぶ、注文画面へ遷移する

● 管理者
　(例)商品を登録する

つまり、Itemモデルひとつをとっても、ユーザーと管理者で見る画面も違ければ、コントローラーの記述も異なるわけです。では、ビューとコントローラーをそれぞれで作成するにはどうしたら良いのかをご説明致します。答えは、ビューとコントローラーで「``user``」、「``admin``」という親ディレクトリを用意して、その中に各モデルのビューやコントローラーを作成するという形になります。

※ 「users」、「admins」というディレクト名だと先ほど作成したdivise用のものと被ってしまい作成できません。そのため単数形の名称にしてあります。どうしても違和感があり気に入らないという場合でしたら、userの代わりに「customers」、「members」などにしても良いかと思います。

```terminal.
$ rails g model Item

$ rails g controller user::items
$ rails g controller admin::items

```
(補足)
● モデルは共通で使用できるので、１つのみの作成で大丈夫です。

●  ``rails g controller (親ディレクトリ名)::（その中に作成するディレクトリ名）``
　　上記のように記述することで、自動的に親ディレクトを作成し、その中にコントローラーを作成してくれます。


```controller:user/items_controller.rb
class User::ItemsController < ApplicationController

end
```

コントローラーのディレクトリを確認すると、userディレクトリ内にitems_controller.rb、adminディレクトリ内にitems_controller.rbとひとつのモデルに対し、２つのコントローラーを作成することが出来ました。
ちなみに、コントローラーを作成するときのコマンドでコロンを2つ(::)入力しましたが、これらはコントローラーのファイルのClass名の部分にもきちんと反映されています。どのディレクトリに準ずるコントローラーか、ということが明確になっております。
<br>

View
---
先ほどコントローラーを作成した際に自動的に``userディレクトリ``と``adminディレクトリ``が作成されましたが、それに伴い、viewの方にも空の``user/itemsディレクトリ``と``admin/itemsディレクトリ``が作成されています。
それぞれのディレクトリの上で右クリックを押し、必要なファイルを作成してください。
<br>

ルーティング
---
次に悩んだポイントがルーティングの作成です。
共通で使用しているモデルのルーティングに関しても、別々に作成する必要があります。
ルーティング作成時のポイントを３つ簡単に押さえておきます。

#####● ``scope``
URL: 変える　　　(例) user/items, user/item/:id
ファイル構成: 変えない

#####● ``namespace``
URL: 変える　　　(例) user/items, user/item/:id
ファイル構成: 指定のパスに変える

#####● ``module``
URL: 変えない　　(例) /items, /item/:id
ファイル構成: 指定のパスに変える


```config/routes.rb
Rails.application.routes.draw do
  root 'homes#top'
  
  devise_for :admins
  namespace :admin do
    resources :items
  end
  
  devise_for :users
  namespace: :user do
    resources :items
  end
end
```

（補足）
今回は、自分自身が分かりやすようにディレクトリを分け、またURLにもuserとadminと表示させ分かりやすくしたかった為、namespaceを採用しました。
ご自身の用途に合わせて選択していただければ良いかと思います。
``scope``、``namespace``、``module``について分かりやすくまとめてくださっているサイトがあり、参考にさせていただきましたので、下記にURLを掲載しておきます。

（参考）
・Railsのroutingにおけるscope / namespace / module の違い
https://qiita.com/ryosuketter/items/9240d8c2561b5989f049
<br>

終わり
---
今回は以上になります。
ざっくりとした説明で分かりにくい点もあるかと思いますが、申し訳ありません。
私自身もプログラミング初心者ですが、同じ様な立場の方に少しでも参考になればと思っています。
また、もし内容に誤りなどがございましたら、ご指摘いただけますと幸いです。