はじめに
deviseを導入すると、簡単に認証機能が実装できて本当に便利なgemですよね!
Ruby on Railsを学び始めて2ヶ月目の頃、ユーザーと管理者に分けてdevise機能を2つ実装したい、こういった時はどうしたら良いのか、また複数のdevise間で両者とも使用するモデルに関してはどうしたら良いのか、と少し悩んだことがありましたので、今回の記事のテーマに選定致しました。
前提
今回説明するモデルを以下の三点に絞らせて頂いております。
● devise User
● devise Admin
● 両者に共通してItemモデルを使用
開発環境
Ruby 2.6.3
Rails 5.2.4.4
gemを導入
gem 'devise'
$ bundle install
ユーザー用、管理者用のdevise機能実装
deviseを複数実装することは意外と簡単です!
User、Adminのように適宜名前を付け、各コマンドを実行すればモデル、ビュー、コントローラーは作成出来ます。
$ 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
model / controller
ここで少し頭を悩ませることになります。
ECサイトを例にあげると、Item(商品)モデルを必ず作成するかと思います。このItemモデルの働きをユーザーと管理者それぞれの立場で考えてみましょう。
● ユーザー
(例)商品を閲覧する、商品の詳細画面へ飛ぶ、注文画面へ遷移する
● 管理者
(例)商品を登録する
つまり、Itemモデルひとつをとっても、ユーザーと管理者で見る画面も違ければ、コントローラーの記述も異なるわけです。では、ビューとコントローラーをそれぞれで作成するにはどうしたら良いのかをご説明致します。答えは、ビューとコントローラーで「user
」、「admin
」という親ディレクトリを用意して、その中に各モデルのビューやコントローラーを作成するという形になります。
※ 「users」、「admins」というディレクト名だと先ほど作成したdivise用のものと被ってしまい作成できません。そのため単数形の名称にしてあります。どうしても違和感があり気に入らないという場合でしたら、userの代わりに「customers」、「members」などにしても良いかと思います。
$ rails g model Item
$ rails g controller user::items
$ rails g controller admin::items
(補足)
● モデルは共通で使用できるので、1つのみの作成で大丈夫です。
● rails g controller (親ディレクトリ名)::(その中に作成するディレクトリ名)
上記のように記述することで、自動的に親ディレクトを作成し、その中にコントローラーを作成してくれます。
class User::ItemsController < ApplicationController
end
コントローラーのディレクトリを確認すると、userディレクトリ内にitems_controller.rb、adminディレクトリ内にitems_controller.rbとひとつのモデルに対し、2つのコントローラーを作成することが出来ました。
ちなみに、コントローラーを作成するときのコマンドでコロンを2つ(::)入力しましたが、これらはコントローラーのファイルのClass名の部分にもきちんと反映されています。どのディレクトリに準ずるコントローラーか、ということが明確になっております。
View
先ほどコントローラーを作成した際に自動的にuserディレクトリ
とadminディレクトリ
が作成されましたが、それに伴い、viewの方にも空のuser/itemsディレクトリ
とadmin/itemsディレクトリ
が作成されています。
それぞれのディレクトリの上で右クリックを押し、必要なファイルを作成してください。
ルーティング
次に悩んだポイントがルーティングの作成です。
共通で使用しているモデルのルーティングに関しても、別々に作成する必要があります。
ルーティング作成時のポイントを3つ簡単に押さえておきます。
#####● scope
URL: 変える (例) user/items, user/item/:id
ファイル構成: 変えない
#####● namespace
URL: 変える (例) user/items, user/item/:id
ファイル構成: 指定のパスに変える
#####● module
URL: 変えない (例) /items, /item/:id
ファイル構成: 指定のパスに変える
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
終わり
今回は以上になります。
ざっくりとした説明で分かりにくい点もあるかと思いますが、申し訳ありません。
私自身もプログラミング初心者ですが、同じ様な立場の方に少しでも参考になればと思っています。
また、もし内容に誤りなどがございましたら、ご指摘いただけますと幸いです。