管理者と顧客で権限を分ける場合

今回のアプリケーションを作成する上で、「管理者」と「顧客」という2つの権限が存在するとします。そのような場合、URLでアクセスできる権限を分けることも多いです。管理者と顧客で権限を分ける場合についての記事を書きたいと思います。
私自身のアウトプットの場となりますので、よろしくお願いします！

##権限ごとにURLを分ける
管理者と顧客で権限を分ける場合、下記のように権限ごとにURLを分ける形するケースがあります。

```ruby:権限ごとに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とコントローラーに分けることができます。

```ruby:routes.rb
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を作成したい時、本来であれば次のようなコマンドを実行していたと思います。

```ruby:ターミナル
 $ rails g controller items
```

しかし、namespaceを使用する場合は、controller名の前にnamespaceで使用するグループ名を入力します。
例えば、adminというグループ名の場合は下記の通りです。

```ruby:ターミナル
 $ rails g controller admin/items
```

これを実行すると、下記のような処理が実行されます。

```ruby:
      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を使用する時は、グループ名で名付けられたフォルダの中にコードファイルが入っている必要があるため
コントローラを作成する時には必ず、グループ名をコントローラー名の前に注意してください。

```ruby:コマンド実行ルール
 $ rails g controller [namespaceのグループ名]/[コントローラー名]
```

##route.rbを編集する
例えば、管理者側で商品関連の操作(表示、追加、編集、削除)を行う際
商品関連のcontroller名をitemsとすると、routes.rbの書き方は次のようになっているはずでした。

```ruby:routes.rb
 Rails.application.routes.draw do
  # (中略)
  resources :items
end
```

しかし、namespaceを使用する場合は、下記のような書き方をします。

```ruby:routes.rb
 Rails.application.routes.draw do
  # (中略)
  namespace :admin do
    resources :items
  end
 end
```

namespaceを適用させている場合、**resources :itemsをnamespace :admin do ~ end**で囲っているのがわかるかと思います。

```ruby:routes.rb
 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でアクセスできる権限を分ける方法になります。
最後までご覧いただきまして、ありがとうございました！