【初心者向け】管理者ユーザーと管理者用controllerの追加方法[Ruby, Rails]

# はじめに
初めまして、Qiita初投稿となります・・・
今、個人（＆プロボノ）である商店街をテーマにした、食べログのようなアプリを作っています。

一般ユーザーはレストラン情報を見ること、コメントを残すことはできますが、レストラン情報の登録（編集・削除も）は管理者のみが行えるようにしたいと思います。

そこで、管理者機能を実装することにしました。

すごーく初心者向けに書いていますので「そんなの知っているよ！」という人はどうぞ読み飛ばしてくださいね。

尚、基本となるユーザー登録・管理機能は、

devise

というGemで実装しています。

# Userに管理者(admin)を追加する

まず、usersテーブルにadminというカラムをboolean型で追加して、デフォルトを0とします。

```ruby
#コンソール
 rails g migration AddAdminToUsers

```

```ruby
#migrationファイル
class AddAdminToUsers < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :admin, :boolean, default: false
  end
end
```

migrationファイルを編集したら、

rake db:migrate

を実施します。

次に、管理者権限をもつユーザーをseedファイルで追加します。

```ruby
# seeds.rb

User.create!(username:  "管理者",
             email: "admin@example.jp",
             password:  "11111111",
             password_confirmation: "11111111",
             admin: true)

```

作成したら、

rake db:seed

で管理権限のあるuser情報をusersテープルに追加します。この辺りの手順は、こちらの[Railsチュートリアル](https://railstutorial.jp/chapters/updating_and_deleting_users?version=4.2#sec-administrative_users)の記述が詳しくて分かり易かったです。

このように管理者を追加することで、

current_user.admin?

などのメソッドが使えるようになります。

管理権限のあるユーザーとしてログインした場合にのみ特定のボタンを表示させる、程度のシンプルな処理で良い場合には、こちらで実装は終わりとなります。

（セキュリティ上いろいろ配慮したい場合には、こちらの[Railsチュートリアル](https://railstutorial.jp/chapters/updating_and_deleting_users?version=4.2#sec-administrative_users)をご覧ください）


# 一般ユーザーと管理ユーザー用のcontrollerを分ける

扱いたい機能が多岐にわたる場合には、管理ユーザー用のcontrollerと一般ユーザーのそれとを分けた方が便利だと思います。私も、今回は以下の方法でcontrollerを分けました。

## app/controllers/admin　下に新たにcontrollerを作成する。
今回は、app/controllers　内に新たに　admin というディレクトリを作成し、そこに、一般ユーザー用のものとは別に、restaurants_controller　を作成したいと思います。

```ruby
# ターミナル
rails g controller admin::restaurants
```

これで、一般ユーザー用と、管理ユーザー用の二つのrestaurants_controller.rbができました。
この時のディレクトリ構造はこんな感じです。

[![Image from Gyazo](https://i.gyazo.com/f70120aaab464d08ca4606a2a4fd1251.png)](https://gyazo.com/f70120aaab464d08ca4606a2a4fd1251)

この時、プログラムはディレクトリ構造からは　/admin/restaurants_controller.rb　の位置を探し当てることができません。

そのため、/admin/restaurants_controller.rb　内には下記のように「Admin::RestaurantsController」の「名前空間」を利用して、現在のディレクトリ構造を明記します。

```ruby
class Admin::RestaurantsController < ApplicationController
 
  #中略

end
```

ついでに、管理ユーザー以外で特定のアクションを実行しようとした場合には、トップページにリダイレクトさせる、
if_not_adminメソッドも作成し、before_actionで設定しました。

```ruby
class Admin::RestaurantsController < ApplicationController
  before_action :if_not_admin

  #中略

  private
  def if_not_admin
    redirect_to root_path unless current_user.admin?
  end
end
```

最後に、edit, show, destroy などのアクションで使用する変数をセットします。

```ruby
class Admin::RestaurantsController < ApplicationController
  before_action :if_not_admin
  before_action :set_restaurant, only: [:show, :edit, :destroy]

 # 中略

  private
  def if_not_admin
    redirect_to root_path unless current_user.admin?
  end

  def set_restaurant
    @restaurant = Restaurant.find(params[:id])
  end
end
```
そのほかのアクションに必要な設定は別途していると思ってください。

## routingの設定

この時のルーティングは下記ように設定しています。
restaurants#indexやrestaurants#show が二つあることになりますが、それぞれ、管理ユーザー（admin)用と、一般ユーザー用とに分けることができました。

```ruby
# routes.rb

resources :restaurants, only: [:index, :show] 
  namespace :admin do
    resources :restaurants, only: [:index, :new, :create, :show,  :edit, :destroy]
  end
end

```

rake routesの結果も下記の通り。

[![Image from Gyazo](https://i.gyazo.com/d9e647f96b59590a2988a1e3fc327ba2.png)](https://gyazo.com/d9e647f96b59590a2988a1e3fc327ba2)

管理者用のページは /admin/restaurants (indexアクション)　など /admin　ディレクトリ下に配置することができています。
これで、管理者用ページと、一般ユーザー用ページが分かれて全体的にわかりやすいサイトの構造になりました＾＾


# Gemについて
なお、管理者画面なども作りたい場合には、

「rails_admin」（管理画面を生成するGem）
「cancancan」（管理者権限を設定するGem）

などがあるようです。
こちらも機会があれば調べてみたいです。

それでは、ここまで読んでくださりありがとうございました＾＾

# 後日追記：管理者ユーザーで投稿機能を実装したときのエラーについて

作成した管理者機能を使って、実際に投稿フォームを作成したらエラーが出たので、対処法を以下に記しておきます。

[form_withでデフォルトのデータ送信先を変更する[Rails]][1]
[1]:https://qiita.com/tanutanu/items/347a15c447626a399bad