gurelog

エンジニアになるため、日々学んだことをまとめています

【Rails】管理者権限を追加する

こんにちは。gureです。

今回はアプリケーションに管理者だけが投稿できる機能をつけたので、備忘録がてら書いておこうと思います。

管理者権限機能をつけてくれるgemもあるそうですが今回はgemを使わずに実装します。

ちなみに管理者権限機能をつけてくれるgem

rails_admin

・active_admin

・Administrate

 前提

前提として基本的なユーザー機能と、投稿するためのテーブル等が存在しているものとします。

①userテーブルにadminカラムを追加

rails g migration AddAdminToUsers admin:boolean

 

をコマンドに入力します。

「userテーブルにadminカラムをboolean型(trueかfalseかでデータを表す)で追加してください」という指示になります。

マイグレーションファイルにデフォルトの値を追加

①によってdb/migrateファイル内にマイグレーションファイルが作られます。

class AddAdminToUsers < ActiveRecord::Migration[6.0]
 def change
  add_column :users, :admin, :boolean
 end
end
管理者権限を持つユーザーだけがadminカラムにtrue、それ以外のユーザーはadminカラムにはfalseの値が入っていてほしいので、
class AddAdminToUsers < ActiveRecord::Migration[6.0]
 def change
  add_column :users, :admin, :boolean, default: false  #追加
 end
end
これで新規登録したユーザーのadminカラムにはデフォルトでfalse(=管理者権限なし)が与えられます。
 
忘れずにコマンドでマイグレーションを実行します。
rails db:migrate

 

③管理者ユーザーの作成

このままユーザー新規登録をしてしまうと、②により自動的に管理者権限なしになってしまうので、管理者ユーザーはseedファイルを使って作成します。

db/seeds.rbに、

User.create!(name: "admin",email: ENV['EMAIL'],password: ENV['PASSWORD'],password_confirmation: ENV['PASSWORD'] ,admin: true)

 を記述します。

admin: trueにしておくことで、このユーザーだけが管理者ユーザーになります。

パスワードなどはコードに直接記載してしまうと悪用される危険性があるので、環境変数を使います。

 

忘れずにコマンドでseedファイルを反映させます。

rails db:seed

これで管理者ユーザーが登録できました。

ログインのページから設定したemailやパスワードでログインすることができます。

 

④管理者ユーザーが使うルーティングを設定

 

今回管理者ユーザーは管理者ユーザーしかいけない投稿ページから投稿を行うため、管理者が使う用のルーティングを別途準備する必要があります。

config/route.ebへ、

 

namespace :admin do
 resources :posts, only: [:index, :new, :create]
end
 

 と記述します。

 

⑤管理者ユーザーが使うコントローラーを作成

 

④と同様に管理者が使う用のコントローラーも準備する必要があります。

コマンドから

rails g controller admin/posts

を実行して管理者用のコントローラーadmin/postsコントローラーを作成します。

 

すると、app/controller/admin/posts_controller.rbというファイルができます。

(他のコントローラーはapp/controller/users_controller.rbのように1段上に入っています)

 

では、管理者用のコントローラーadmin/postsの中身を記述していきましょう。

 

⑥管理者用のコントローラーを記述

まずは、管理者ユーザーしか入れない設定をします。

before_actionにadmin_userを下記のように設定し、

 

class Admin::PostsController < ApplicationController
 before_action :admin_user

 private
 def admin_user
  unless current_user.admin?
   redirect_to root_path
  end
end
end

 

current_userがadmin: trueでなければトップページにリダイレクトされるようにします。

 

次に、管理者が投稿する用のnewアクションとcreateアクション、投稿を確認するためのindexアクションを記述します。

 

class Admin::PostsController < ApplicationController
 before_action :admin_user
 
 def index
  @post = Post.all
 end
 
 def new
  @post = Post.new
 end

 def create
  @post = Post.new(post_params)
 if @post.valid? 
  @post.save
  redirect_to :index
 else
  render :new
 end
end

private
 def admin_user
  unless current_user.admin?  
  edirect_to root_path
  end
 end

 def post_params
  params.require(:post).permit(:image, :text, :title) 
 end
end

この辺りは通常のコントローラーと一緒ですね。

 

⑦管理者用のビューを作成 

indexのビューは通常のビューと特に変わりないので割愛します。

newのビューは少し通常と異なるので注意が必要です。

 

 app/views/new.html.erbを以下のように記述しました。

<h1>投稿</h1>
 <%= form_with model: [ :admin, @post ], url: admin_posts_path local: true do |f|%>
  <p>タイトル</p>
  <%= f.text_field :title %>
  <p>画像</p>
  <%= f.file_field :image %>
  <p>本文</p>
  <%= f.text_field :text %>
  <%= f.submit %>
<% end %>
 

form_withでユーザーが入力した情報はadmin/postsコントローラーのcreateアクションに行ってほしいので、modelには[ :admin, @post]を指定してあげます。

さらにralis routesからcreateアクションのprefix(admin_posts)をurlに指定してあげます。これは今回の場合は管理者以外のユーザーが使用するpostsコントローラーが存在していたためです。

 

これで管理者権限の追加は完成です。とても長くなってしまいました。

 

参考資料 

https://kyoto-diary.com/rails-admin/

https://qiita.com/tanutanu/items/347a15c447626a399bad