RailsでCanCanCanを使った権限管理
導入
Railsアプリケーションにおいて、ユーザーによって操作できるデータを制限する場合、CanCanCan
は非常に有力なツールです。このガイドでは、Staff
モデルが自身のデータのみを編集できるようにする設定方法を紹介します。
前提条件
この設定を行う前に、CanCanCan
ジェムがアプリケーションにインストールされていることを確認してください。
gem 'cancancan', '~> 3.0'
そして、bundle install
を実行します。
Ability クラスの設定
CanCanCan
は Ability
クラスを使用して、誰が何をできるかを定義します。Staff
が自分自身のプロファイルのみ更新できるように設定しましょう。
# app/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # ゲストユーザーの場合は新しいユーザーインスタンス
case user
when Staff
can :manage, Staff, id: user.id # スタッフは自身のデータのみ操作可能
can :read, Company, id: user.company_id # スタッフは自身が所属する企業を閲覧可能
when Company
can :manage, Company, id: user.id # 企業は自身のデータのみ操作可能
can :manage, Staff, company_id: user.id # 企業は所属するスタッフのデータを管理可能
when Customer
can :manage, Customer, id: user.id # 顧客は自身のデータのみ操作可能
can :read, Company # 顧客は全企業を閲覧可能
when AdminUser
can :manage, :all # 管理ユーザーは全データに対する操作権限を持つ
else
# ゲストユーザーの権限
can :read, Company # ゲストは企業情報の閲覧のみ可能
end
end
end
コントローラの設定
StaffsController
に load_and_authorize_resource
メソッドを追加して、CanCanCanがリソースのロードと権限チェックを自動で行うようにします。
# app/controllers/staffs_controller.rb
class Staffs::RegistrationsController < Devise::RegistrationsController
load_and_authorize_resource :class => 'Staff'
def edit
end
def update
if @staff.update(staff_params)
redirect_to @staff, notice: 'スタッフ情報が更新されました。'
else
render :edit
end
end
private
def staff_params
params.require(:staff).permit(:name, :email, :department)
end
end
エラーハンドリング
current_user
メソッドが定義されていない場合、current_ability
メソッドをオーバーライドしてカスタムユーザーメソッドを指定する必要があります。
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
# アクセス権限がない場合に元いたページに戻す。直接URLを入力して訪れた場合などはフォールバックでルートパスへ。
rescue_from CanCan::AccessDenied do |exception|
redirect_to request.referer || root_url, alert: "アクセス権限がありません。"
end
def current_ability
@current_ability ||= Ability.new(current_staff)
end
end
まとめ
この設定により、スタッフは自分自身のプロフィール情報のみを編集することが可能となります。CanCanCan
を使用することで、複雑な権限設定も容易に実装でき、セキュリティの向上にもつながります。