【初心者向け】管理者ユーザーと管理者用controllerの追加方法[Ruby, Rails]
はじめに
どうもこんにちは、エンジニアとして就職を目指しているタヌキです。 2回連続でエンジニア(勉強中)っぽいことを書かなかったので、今回は勉強のお話をします。
今、個人でこんな感じのすごろくアプリを作っています。
武蔵新城(JR南武線)周辺で「地域をもっと面白くしよう!」という人たちの集まりで作った、こんなすごろく(紙版:こちらも途中のものです。すみません。マス目の中にレストランを書き込んで、出た目のレストランに行って美味しいご飯を食べるという作りになっています)を(勝手に)アプリにしてみました。
ただし、地域のお店の情報を勝手にすごろくやアプリに登録してしまうといけないようなので、レストラン情報の登録(編集・削除も)は管理者のみが行えるようにしたいと思います。
そこで、管理者機能を実装することにしました。
すごーく初心者向けに書いていますので「そんなの知っているよ!」という人はどうぞ読み飛ばしてくださいね。
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でselect boxを実装した時の設定が色々勉強になったので、それについて投稿してみたいと思います。
6/13追記:
6/11投稿時点では、edit, showなどの一部アクションが表示できないエラーが発生しておりましたが、その後無事解決しました。(単純な記述ミスでした。トホホ・・・)