はじめに
初めまして、Qiita初投稿となります・・・
今、個人(&プロボノ)である商店街をテーマにした、食べログのようなアプリを作っています。
一般ユーザーはレストラン情報を見ること、コメントを残すことはできますが、レストラン情報の登録(編集・削除も)は管理者のみが行えるようにしたいと思います。
そこで、管理者機能を実装することにしました。
すごーく初心者向けに書いていますので「そんなの知っているよ!」という人はどうぞ読み飛ばしてくださいね。
尚、基本となるユーザー登録・管理機能は、
devise
というGemで実装しています。
Userに管理者(admin)を追加する
まず、usersテーブルにadminというカラムをboolean型で追加して、デフォルトを0とします。
#コンソール
rails g migration AddAdminToUsers
#migrationファイル
class AddAdminToUsers < ActiveRecord::Migration[5.2]
def change
add_column :users, :admin, :boolean, default: false
end
end
migrationファイルを編集したら、
rake db:migrate
を実施します。
次に、管理者権限をもつユーザーをseedファイルで追加します。
# seeds.rb
User.create!(username: "管理者",
email: "admin@example.jp",
password: "11111111",
password_confirmation: "11111111",
admin: true)
作成したら、
rake db:seed
で管理権限のあるuser情報をusersテープルに追加します。この辺りの手順は、こちらのRailsチュートリアルの記述が詳しくて分かり易かったです。
このように管理者を追加することで、
current_user.admin?
などのメソッドが使えるようになります。
管理権限のあるユーザーとしてログインした場合にのみ特定のボタンを表示させる、程度のシンプルな処理で良い場合には、こちらで実装は終わりとなります。
(セキュリティ上いろいろ配慮したい場合には、こちらのRailsチュートリアルをご覧ください)
一般ユーザーと管理ユーザー用のcontrollerを分ける
扱いたい機能が多岐にわたる場合には、管理ユーザー用のcontrollerと一般ユーザーのそれとを分けた方が便利だと思います。私も、今回は以下の方法でcontrollerを分けました。
app/controllers/admin 下に新たにcontrollerを作成する。
今回は、app/controllers 内に新たに admin というディレクトリを作成し、そこに、一般ユーザー用のものとは別に、restaurants_controller を作成したいと思います。
# ターミナル
rails g controller admin::restaurants
これで、一般ユーザー用と、管理ユーザー用の二つのrestaurants_controller.rbができました。
この時のディレクトリ構造はこんな感じです。
この時、プログラムはディレクトリ構造からは /admin/restaurants_controller.rb の位置を探し当てることができません。
そのため、/admin/restaurants_controller.rb 内には下記のように「Admin::RestaurantsController」の「名前空間」を利用して、現在のディレクトリ構造を明記します。
class Admin::RestaurantsController < ApplicationController
#中略
end
ついでに、管理ユーザー以外で特定のアクションを実行しようとした場合には、トップページにリダイレクトさせる、
if_not_adminメソッドも作成し、before_actionで設定しました。
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 などのアクションで使用する変数をセットします。
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)用と、一般ユーザー用とに分けることができました。
# routes.rb
resources :restaurants, only: [:index, :show]
namespace :admin do
resources :restaurants, only: [:index, :new, :create, :show, :edit, :destroy]
end
end
rake routesの結果も下記の通り。
管理者用のページは /admin/restaurants (indexアクション) など /admin ディレクトリ下に配置することができています。
これで、管理者用ページと、一般ユーザー用ページが分かれて全体的にわかりやすいサイトの構造になりました^^
Gemについて
なお、管理者画面なども作りたい場合には、
「rails_admin」(管理画面を生成するGem)
「cancancan」(管理者権限を設定するGem)
などがあるようです。
こちらも機会があれば調べてみたいです。
それでは、ここまで読んでくださりありがとうございました^^
後日追記:管理者ユーザーで投稿機能を実装したときのエラーについて
作成した管理者機能を使って、実際に投稿フォームを作成したらエラーが出たので、対処法を以下に記しておきます。
[form_withでデフォルトのデータ送信先を変更する[Rails]][1]
[1]:https://qiita.com/tanutanu/items/347a15c447626a399bad