【Rails6】deviseとcancancanとactive adminで権限管理をする方法

deviseとcancancanとactive adminで権限管理

前提として、deviseとactive adminを導入済みとします。

今回は、有料会員と無料会員で権限を分け、表示内容を分けるところまでやりたいと思います。

決済システムまで組み込み、完全に自動的に分けるのがベストですが、今回は、会員登録時にはデフォルトで無料会員の権限を付与し、active adminの管理画面で手動で有料会員の権限にアップグレードさせるという仕様で行きます。

権限管理

Gemfileの更新

Gemfileに下記を追加。

gem 'cancancan'
$ bundle install

deviseのuserモデルにroleカラムの追加

deviseでデフォルト作成されるテーブルを使用しているため、そこにroleという権限を管理するカラムを追加します。

カラムの追加なので、マイグレーションファイルを作成します。

カラムの追加方法は下記の様にする。

add_{追加するカラム名}_to_{カラムを追加するモデル名を複数形で}

今回の場合は、

$ rails g migration add_role_to_users role:integer

そして、生成されたマイグレーションファイルを以下のように修正し、rails db:migrateします。

class AddRoleToUsers < ActiveRecord::Migration[6.0]
  def change
    add_column :users, :role, :integer, null: false, default: 2
  end
end
$ rails db:migrate

モデルの修正

新しいカラムを作成したので、モデルを修正します。

enumを使用し、この文字列ならばこの数値をDBに入れるよう定義します。

user.rbに下記を追加。

class User < ApplicationRecord
  devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :confirmable, :lockable, :timeoutable, :trackable

  # 追加
  enum role: { paid: 1, free: 2 }
end

Abilityクラスの作成

CanCanCanでキモとなるAbilityクラスを作成します。

$ rails g cancan:ability

これで、app/models/ability.rbが生成されます。

なお、今回は冒頭で話した通り、paidfreeの2つの権限を作り、有料会員と無料会員で権限を分け、表示内容を分けるという仕様で進めます。

app/models/ability.rbを下記の様に編集。

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new
    if user.paid?
      can :update, :all
    end

    if user.free?
      can :read, :all
    end
  end
end

権限には基本5種類あり、paidにはupdateを、freeにはreadを割り当てました。

  • read: 読み込み
  • create: 新規作成
  • update: 更新
  • destroy: 削除
  • manage: 全て

canの後に許可したい権限を指定し、第2引数で許可する場所を指定します。

確認のためにビューを修正

<% if can? :update, current_user %>
  <h1>有料会員が見れます。</h1>
<% end %>
<% if can? :read, current_user %>
  <h1>無料会員が見れます。</h1>
<% end %>

ブラウザで確認する

もしかしたら、サーバーを再起動しないとエラーが起きるかも。

まずは、roleの値が2のユーザーで試すと、(free)

有料会員が見れます。

と表示されています。

次に、paid権限を確認したいのですが、ここでは管理画面で権限変更ができる様にします。

active adminで権限変更ができる様にする

app/admin/users.rbを下記の様にする。

ActiveAdmin.register User do
  permit_params :username, :email, :role, :confirmation_token

  index do
    column :id
    column "ユーザー名", :username
    column "メースアドレス", :email
    column "権限", :role
    column "パスワード確認トークン", :confirmation_token
    column "パスワード確認時刻", :confirmed_at
    column "パスワード確認送信時刻", :confirmation_sent_at
    column "作成日時", :created_at
    # column :updated_at
    actions
  end

  form do |f|
    f.inputs do
      f.input :username
      f.input :email
      f.input :role
      f.input :password
    end
    f.actions
  end
end

管理項目のカラムにroleを追加することで権限の変更が簡単にできる様になります。

権限管理

この様にできればあとは権限が反映されているかの確認をブラウザでも行い、完了です。

他にもこんな記事があります!