今回のアプリケーションを作成する上で、「管理者」と「顧客」という2つの権限が存在するとします。そのような場合、URLでアクセスできる権限を分けることも多いです。管理者と顧客で権限を分ける場合についての記事を書きたいと思います。
私自身のアウトプットの場となりますので、よろしくお願いします!
##権限ごとにURLを分ける
管理者と顧客で権限を分ける場合、下記のように権限ごとにURLを分ける形するケースがあります。
顧客がアクセスする商品一覧ページのURL : https://xxxxx.com/items
管理者がアクセスする商品一覧ページのURL : https://xxxxx.com/admin/items
この実装を可能とする方法として、namespaceを用いて実装します。
また、URLを分けることで生じるメリットについても説明いたします。
##namespaceとは
namespaceとは、決めた名前でルーティングのグループ分けをするための仕組みです。
今回はECサイトを作成しているとします。この場合、買い物をする会員と、サイトを管理する管理者が存在します。
例えば、/itemsという商品一覧を表示するURLがあるとします。
このページの機能やデザインは会員側と管理者側で違います。if文やコントローラーを二つ作成するなどして実装することも可能ですが、会員側・管理者側を 1 つのコントローラー/ビューに記述することになるため、コードが複雑になります。また、コントローラーの名前とモデル名が統一されていないことでややこしさが増すため、設計上余り好ましくありません。
それらを解決するのが namespace(名前空間)になります。
namespace(名前空間)で行う事は下記の通りです。
・同じデータを扱うコントローラー/ビューを、会員側と管理者側で計二つ作成し、それらを各フォルダに分けて管理する。
・会員側と管理者側によって、ルーティング(URL 等)をグループ分けして管理する。
フォルダを分けてコントローラーを管理することでadminフォルダ内のコントローラーは管理者側、customerフォルダ内のコントローラーは会員側、のように役割ごとに分けることができます。
また、管理者側と会員側でコントローラーを分けることによって会員側のitemsコントローラー(customer/items_controller.rb)にはcreateアクションを作らない・ルーティングを設定しないということも容易にすることができます。
##ルーティング
ルーティングでは、下記のようにroutes.rbに記載することで会員側のURLとコントローラー・管理者側のURLとコントローラーに分けることができます。
Rails.application.routes.draw do
# 会員側のルーティング設定
get 'items' => 'customer/items#index'
# 管理者側のルーティング設定
namespace :admin do
get 'items' => 'admin/items#index'
end
end
このように、namespaceを使用すると、フォルダ構成やURLを指定することができます。
##実装の手順
itemsというcontrollerや、それに紐づいたviewを作成したい時、本来であれば次のようなコマンドを実行していたと思います。
$ rails g controller items
しかし、namespaceを使用する場合は、controller名の前にnamespaceで使用するグループ名を入力します。
例えば、adminというグループ名の場合は下記の通りです。
$ rails g controller admin/items
これを実行すると、下記のような処理が実行されます。
create app/controllers/admin/items_controller.rb
invoke erb
create app/views/admin/items
invoke test_unit
create test/controllers/admin/items_controller_test.rb
invoke helper
create app/helpers/admin/items_helper.rb
invoke test_unit
invoke assets
invoke coffee
create app/assets/javascripts/admin/items.coffee
invoke scss
create app/assets/stylesheets/admin/items.scss
これは、controllerやviewなどのコードのファイルを作成する時に、adminというフォルダ内に自動的に保存するコマンドになっています。
namespaceを使用する時は、グループ名で名付けられたフォルダの中にコードファイルが入っている必要があるため
コントローラを作成する時には必ず、グループ名をコントローラー名の前に注意してください。
$ rails g controller [namespaceのグループ名]/[コントローラー名]
##route.rbを編集する
例えば、管理者側で商品関連の操作(表示、追加、編集、削除)を行う際
商品関連のcontroller名をitemsとすると、routes.rbの書き方は次のようになっているはずでした。
Rails.application.routes.draw do
# (中略)
resources :items
end
しかし、namespaceを使用する場合は、下記のような書き方をします。
Rails.application.routes.draw do
# (中略)
namespace :admin do
resources :items
end
end
namespaceを適用させている場合、resources :itemsをnamespace :admin do ~ endで囲っているのがわかるかと思います。
username:~/environment/アプリケーション名 $ rails routes
Prefix Verb URI Pattern Controller#Action
admin_items GET /admin/items(.:format) admin/items#index
POST /admin/items(.:format) admin/items#create
new_admin_item GET /admin/items/new(.:format) admin/items#new
edit_admin_item GET /admin/items/:id/edit(.:format) admin/items#edit
admin_item GET /admin/items/:id(.:format) admin/items#show
PATCH /admin/items/:id(.:format) admin/items#update
PUT /admin/items/:id(.:format) admin/items#update
DELETE /admin/items/:id(.:format) admin/items#destroy
# 以下略
URLの最初に/admin/が追加されています。
このように、権限によってURLを分ける時に、namespaceとして切り分けて管理することが可能になります。
以上がnamespaceを用いて、URLでアクセスできる権限を分ける方法になります。
最後までご覧いただきまして、ありがとうございました!