activeadmin利用時において、ユーザーと管理ユーザーをUser/AdminUserのような別モデルにせず、どちらも同じUserとして管理しているとします。
その時、管理者としてのroleをもたないユーザーにはactiveadminの管理者画面(dashboardなど)にアクセスすらさせたくない場合があります。
そんな時の設定方法をまとめました。
以下手順。
1. Userに権限を分けて与えるためのrole(役割)を付与する
roleを付与するmigrationファイル生成
$ rails g migration AddRoleToUser role:integer
migrationファイルの中身を確認
# db/migrate/xxxxxxxxxxxxx_add_role_to_user.rb
class AddRoleToUser < ActiveRecord::Migration
def change
add_column :users, :role, :integer, default:0
end
end
マイグレーション実行
$ rake db:migrate # Userにroleが付与されたか rails c などで確認しておく
##2. ability.rbにてactiveadminの管理画面にアクセスできないように設定する
述語メソッドを利用可能にする
# models/user.rb
class User < ActiveRecord::Base
enum role: %i(user admin) # roleはuserとadminの2つとしておく。もちろん3つ以上でもok
end
権限管理でactiveadminのページにはadminユーザー以外アクセス出来ないように変更
# models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
cannot :manage, :all
user ||= User.new
if user.admin?
can :manage, :all
else
can :read, :all
cannot :manage, ActiveAdmin::Page # roleがadmin以外であればactiveadminの各種ページにアクセス出来ないようにした
end
end
end
なお、このままの状態でactiveadminの画面にアクセスすると**「アクセス権限ない -> dashboardにリダイレクト -> アクセス権限ない -> リダイレクト ...」**とリダイレクトループに陥ってしまう。
そこでアクセス権限がない場合のactiveadminの挙動を変更する
- アクセス権限がない場合の挙動を設定
ActiveAdmin.setup do |config|
#(中略)
# == User Authorization = 認可. どのリソースにアクセスできるのか
#(中略)
# You can specify a method to be called on unauthorized access.
# This is necessary in order to prevent a redirect loop which happens
# because, by default, user gets redirected to Dashboard. If user
# doesn't have access to Dashboard, he'll end up in a redirect loop.
# Method provided here should be defined in application_controller.rb.
config.on_unauthorized_access = :access_denied # ここをコメントイン.
#(中略)
end
application_controller.rbでaccess_deniedを上書きする。
redirect先をアクセス可能なページに変更。(ここでは表のTOPページを指定している)
# controllers/application_controller.rb
class ApplicationController < ActionController::Base
#(中略)
# cancancanでaccess_deniedされた時の挙動を記述
def access_denied(exception)
redirect_to root_path, notice: "only users which have a admin role can access the page you've accessed."
end
#(中略)
end
終わりに
以上です。
誤りがあれば随時コメントいただけると幸いです!