sessanの日記

主に開発技術関連でお勉強したことをまとめていくサイトです。

ActiveAdminにCanCanを使った権限機能を追加する(1)

最初から順序だてて解説しているブログがないので、書いとく。今日は準備するところまで。

前提条件

  • 既にActiveAdminを導入している
  • ActiveAdminは0.4.4を使用している

作業の流れ

  1. gemにCanCanを追加
  2. CanCanのロール管理用テーブルを追加

1. gemにCanCanを追加する

cancanは自分の環境では1.6.7を使った。Gemfile.lockに書いているcancanのバージョンが古い場合は、注意すること。

Gemfile

# 権限管理用のライブラリ
gem 'cancan'

2. CanCanのロール管理用テーブルを追加

ここは、CanCanがやってくれず、開発者に実装が任せられている。色々なやり方はあると思うが、以下を考慮して、DBのテーブルでActiveAdminのユーザーのロールの割り当てを管理することにした。この管理テーブルは業務アプリケーションを設計したことがある人にとっては、よくある感じだと思う。

  • 一人の管理ユーザーに、複数のロールを割り当てられるようにし、ロールには複数のユーザーを割り当てるようにしとく(つまり、多対多にする。なぜなら、こうしとけば1対多でも多対1でも、後で変更になったときに両方対応できるから。)
  • DBにデータを追加するだけで新しいロールの割り当てをすることができ、サーバの再起動が不要(※ただし、新しいロールを追加するとCanCanの権限定義のクラスを変更する必要が出てくるので、コードの修正とサーバ再起動が必要になる)

作るモデル

  • admin_role
  • admin_role_assign

(admin_userモデルは既にある想定)

> rails g model admin_role name:string
> rails g model admin_role_assign admin_role_id:integer admin_user_id:integer

生成されたマイグレーションファイルに追記して、admin_role_assignにはインデックスをつけておく。

    add_index(:admin_role_assigns, :admin_role_id, {:name => :index_admin_role_assigns_on_admin_role_id})
    add_index(:admin_role_assigns, :admin_user_id, {:name => :index_admin_role_assigns_on_admin_user_id})

マイグレーションを実行して、テーブルを実際に作成

> rake db:migrate

追加したモデルに多対多のリレーションの定義をしておく。

class AdminRole < ActiveRecord::Base
  attr_accessible :name

  has_many :admin_role_assigns
  has_many :admin_users, :through => :admin_role_assigns

end

class AdminUser < ActiveRecord::Base
  has_many :admin_role_assigns
  has_many :admin_roles, :through => :admin_role_assigns

# -----途中省略-----#
end

# coding : utf-8
class AdminRoleAssign < ActiveRecord::Base
  attr_accessible :admin_role_id, :admin_user_id

  belongs_to :admin_user
  belongs_to :admin_role
end