rails-adminを導入
管理画面を作成する手間を省くことが出来るrails-aminを導入します。 ゲストとログインユーザーを分ける事はしましたが、現状は管理ユーザーとログインユーザーの区別はありません。その区別をするためのGemも含めて作業を進めて行きます。
index
- 1 rails-adminの導入
- 2 認証系のGemの導入
- 3 実装
- 4 権限の作成
- 5 その他
1 rails-adminの導入
gem 'rails_admin', ['>= 3.0.0.rc3', '< 4']
$ bundle install
$ bin/rails g rails_admin:install
管理画面用のURLを聞かれるので、そのままENTERで /adminにする。
これだけで ***/admin で管理画面にアクセス出来ます。 この時点では認証は一切関係ないので、ログイン無しでも/admin画面にアクセス出来ます。
To begin with, you may be interested in setting up Devise, CanCanCan or Papertrail!
先にあったDeviceなどでrouteに制限を掛けても良いですが、目的は 一般ユーザーと管理ユーザーを分ける事なので、ドキュメントにあるように、CanCanCanなどを入れて権限を分けて行きましょう。
2 認証系のGemの導入
2-1 Devise
Deviseでの作業に関してはこちらを参考にしてください。
2-2 cancancan
cancancanを利用すれば、指定したユーザーの役割に合わせて、アクセスページや保存、閲覧の権限などを細かくわける事が出来るようになります。
Gemfile追加
$ gem 'cancancan'
bundle install
3 実装
1つの権限のみを実装するのであれば、 - UserとRoleというデータベースだけで済みます
今回は、1人が複数の役割を持てる形で権限関係を実装していきます。 - User ※実装済み - Role ※役割の名前を入れるテーブル - UserRole ※UserとRoleの関係性(association)の為のテーブル 上記のDBテーブルを準備します。
3-1 Role - ロールの作成
$ bin/rails generate migration CreateRoles
migrationファイルに追加
class CreateRoles < ActiveRecord::Migration[7.0]
def change
create_table :roles do [t]
#@note 権限名称を追加
t.string :name,null: false
t.timestamps
end
end
end
3-2 UserRole - ユーザー個別のロールとの関係性テーブルの作成
$ bin/rails generate migration CreateUserRoles
migrationファイルに追加
class CreateUserRoles < ActiveRecord::Migration[7.0]
def change
create_table :user_roles do |t|
#@note 外部キー関係を定義
t.references :user,foreign_key: true,null: false
t.references :role,foreign_key: true,null: false
t.timestamps
#@note インデックス(複合キー)を作成
t.index [:user_id, :roe_id], unique: true
end
end
end
最後にmigrateしましょう。
$ bin/rails db:migrate
- 補足 ※ index 複合キーについて
3-3 モデル関係の実装
今回先にmigrationファイルは作ってるので --skipオプションをつけて、モデル類をジェネレートしていきます。
3-3-1 Role
bin/rails generate model Role --skip
skip db/migrate/20220304050632_create_roles.rb
create app/models/role.rb
invoke test_unit
create test/models/role_test.rb
create test/fixtures/roles.yml
app/models/role.rb
class Role < ApplicationRecord
has_many :user_roles
has_many :users, through: :user_roles
validates :name, presence: true
end
3-3-2 UserRole
$ bin/rails generate model UserRole --skip
skip db/migrate/20220304035717_create_user_roles.rb
create app/models/user_role.rb
create test/models/user_role_test.rb
create test/fixtures/user_roles.yml
app/models/user_role.rb
class UserRole < ApplicationRecord
belongs_to :user
belongs_to :role
end
3-3-3 Userモデルに追加
一人が持てる役割Roleが複数あることを定義
class User < ApplicationRecord
# 下記2点を追加
has_many :user_roles
has_many :roles, through: :user_roles
# こちらは追加済みのdeviseの設定
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :confirmable
# @note cancancanでの、権限の確認用の関数追加
def admin
self.roles.find_by(name: "admin")
end
end
のちほど追加するAbilityで利用する user.admin 関数を追加しています。
4 権限の作成
4-1 Ability
権限毎のルールを作成するクラスを生成しておきます。 cancanの機能に依存したモデルを作成します。
$ bin/rails generate cancan:ability
create app/models/ability.rb
4-2 リダイレクト設定、cancancanの有効化
- リダイレクト
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
#@note CanCanで非認証の場合に root_pathにリダイレクト
rescue_from CanCan::AccessDenied do |exception|
redirect_to main_app.root_path, alert: exception.message
end
end
- cancancanの有効化
rails_adminの設定部分に追加、コメントアウト解除を行います。
config/initializers/rails_admin.rb
...
# @note 追加
config.parent_controller = 'ApplicationController'
### Popular gems integration
## == Devise ==
config.authenticate_with do
warden.authenticate! scope: :user
end
config.current_user_method(&:current_user)
## == CancanCan ==
config.authorize_with :cancancan
...
4-3 role データ投入
シーダーに設定して利用する権限名(admin,manager,read_only)を追加しておきます。
db/seeds.rb
%w[
admin
manager
read_only
].each do |name|
Role.create!(
{name: }
)
end
4-4 権限ごとにルールを設定
モデルにadmin判定を入れてます。
app/models/user.rb
# @note 権限の確認
def admin
self.roles.find_by(name: "admin")
end
abilityに各roleでの役割を入れます。
app/models/ability.rb
user ||= User.new
#puts user;
can :read, :all # 全閲覧、読み込み可能
return unless user && user.admin #以下 adminであれば管理画面にアクセス、編集可能
can :access, :rails_admin # 管理画面にアクセス可能に
can :manage, :all # 編集可能に
今回は最低限 adminだけの役割を追加してます。
※ 参考
4-4 userデータ投入
シーダーを利用して初期ユーザーメールとパスワードを入力しておきましょう。
# userの作成
u = User.create!({
email: "****",
password: "****",
confirmed_at: Date.today()
})
# 初期ユーザーをadminに指定
u.user_roles.create({
role_id: Role.find_by(name: "admin").id,
})
5 その他
5-1 paper-trailでrails-adminの管理画面に変更履歴を表示する。
paper_trailでRailsのモデルに対する変更履歴を保存する
Gemfileに追加
gem 'paper_trail'
bundle install
- paper_trailをジェネレートします。
bin/rails g paper_trail:install --with-associations bin/rails db:migrate
- コメントアウトして paper_trailを有効化
config/initializers/rails_admin.rb
## == PaperTrail ==
config.audit_with :paper_trail, 'User', 'PaperTrail::Version' # PaperTrail >= 3.0.0
## With an audit adapter, you can add:
#この部分もコメントアウト
history_index
history_show
- 利用したいmodelに下記を追加します
has_paper_trail
これでreails-adminのトップにHistoryが表示されるようになります。
5-2 herokuの無料枠の中でエラーログを収集する方法として
papertrailで、無料枠内でエラーログ を収集し続ける