Index

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 複合キーについて

ユーザが本質的に1日1回しかできない投稿

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だけの役割を追加してます。

※ 参考

rails_admin

rails_adminでのcancancan

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

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で、無料枠内でエラーログ を収集し続ける

5-3 その他3 日本語化

rails-adminの日本語化

最新記事一覧

続きを見る

関連コンテンツ

カテゴリー一覧

TOP フルスタックエンジニアを目指すに方々へ 2022年3月12日 Deviseのbootstrap5 対応