2021年12月7日
プログラミング
gem cancancanを使ってみた!
はじめに
この記事は新しい技術にチャレンジし続けるpalanのアドベントカレンダーDay7の記事です!
昨日は「RealityConposerのオブジェクトトラッキングでスノードームを作ってみる!」についての記事でした。
今回は権限管理を行うときに便利なgem cancancanを使ってみました!
今回使用する環境
- Ruby: 2.7.4
- Ruby on Rails: 6.1.4
- cancancan: 3.3.0
事前準備
今回はadmin_usersテーブルにinteger型でroleを追加します
t.integer :role, null: false, default: 0
admin_user.rb
enum role: { editor: 0, sales: 1, system_admin: 99 }
cancancan の導入
Gemfile
gem 'cancancan'
$ bundle install
を実行
権限の設定
Ability クラスの作成
app/models/ability.rbを作成
$ rails generate cancan:ability
Ability クラスの設定
class Ability
include CanCan::Ability
def initialize(admin_user)
#基本的には権限をモデルごとに設定する
if admin_user.system_admin?
can :manage, :all
# 全てのコントローラーで全てのアクションが実行できる
elsif admin_user.editor?
can :manage, Article
cannot :destroy, Article
# Articleのdestroyを除く全てのアクションが実行できる
elsif admin_user.sales?
can :read, Company
# Companyの読み取り(index, show)だけができる
end
end
end
設定できるアクション
manageの他に以下4つのエイリアスが存在します。
ちなみにmanageには以下の基本のCRUD以外にも自分で追加したsearchアクションなども含まれるので注意しましょう!
POINT!!
read: [:index, :show]
create: [:new, :create]
update: [:edit, :update]
destroy: [:destroy]
権限設定の利用
load_and_authorize_resourceメソッドを利用すると、自動的にリソースの取得と権限チェックを行ってくれます。
article_controller.rb
class ArticlesController < ApplicationController
load_and_authorize_resource
def index
# 読み取り可能な@articlesが読み込まれている
end
def show
# @articleが読み込まれて権限もチェックされている
end
def create
# @articleが読み込まれてarticle_paramsがセットされ、権限もチェックされている
@article.create
end
def edit
# @articleが読み込まれて権限もチェックされている
end
def update
# @articleが読み込まれて権限もチェックされている
@article.update(article_params)
end
def destroy
# @articleが読み込まれて権限もチェックされている
@article.destroy
end
private
def article_params
params.require(:article).permit(:body)
end
end
AccessDeniedの制御
権限がない際に時に発生するCanCan::AccessDenied exceptionをApplicationControllerで制御します。
application_controller.rb
class ApplicationController < ActionController::Base
# 権限が無いページへアクセス時の例外処理
rescue_from CanCan::AccessDenied do |exception|
redirect_to root_path, flash: { danger: '権限がありません' }
end
操作可能なリソースの条件設定
ユーザーがオーナーの記事だけ読み書き削除できるようにしたい
Article.rb
belongs_to :owner, class_name: 'AdminUser', foreign_key: :admin_user_id
Ability.rb
can manage, Aeticle, owner: admin_user
ユーザーがCompanyに紐づくいずれかのOrderの営業担当の時だけCompanyの読み取りをできるようにしたい
Company.rb
scope :orders_in_charge_of_sales, ->(admin_user) { where(id: Order.where(sales_person: admin_user).pluck(:company_id)) }
Order.rb
belongs_to :company
belongs_to :sales_person, class_name: 'AdminUser'
Ability.rb
can :read, Company, Company.orders_in_charge_of_sales(admin_user) do |record|
# レコードの権限判定
record.orders.any? { |order| order.sales_person == admin_user }
end
ハッシュでは表現できない複雑な条件を指定するときはブロックを利用します。
indexアクションでアクセス可能な全リソースを取得するときのためにスコープを渡し、ブロック内では個別のレコードの権限判定を記述します。
更に詳しくはcancancan のWiki 「Define abilities with blocks」の項目 をご覧ください。
まとめ
cancncanはとても便利なのですが、最初はハッシュで表現できない条件などの設定に少し苦労しました。この記事が何かのお役に立てれば幸いです!
Rubyのお仕事に関するご相談
Bageleeの運営会社、palanではRubyに関するお仕事のご相談を無料で承っております。
zoomなどのオンラインミーティング、お電話、貴社への訪問、いずれも可能です。
ぜひお気軽にご相談ください。
この記事は
参考になりましたか?
0
0
関連記事
2021年12月22日
RDBでセットメニューを表現する方法
2021年12月11日
Railsでツリー構造アプリを作ってみた
2021年12月9日
モデルに書いていたメソッドをPOLOに切り出してみた!
2021年12月7日
gem cancancanを使ってみた!
2021年11月15日
CustomCopで命名規則を作ってみた
2021年10月29日
clambyを利用したウイルススキャン
簡単に自分で作れるWebAR
「palanAR」はオンラインで簡単に作れるWebAR作成ツールです。WebARとはアプリを使用せずに、Webサイト上でARを体験できる新しい技術です。
palanARへpalanでは一緒に働く仲間を募集しています
正社員や業務委託、アルバイトやインターンなど雇用形態にこだわらず、
ベテランの方から業界未経験の方まで様々なかたのお力をお借りしたいと考えております。
運営メンバー
Eishi Saito 総務
SIerやスタートアップ、フリーランスを経て2016年11月にpalan(旧eishis)を設立。 マーケター・ディレクター・エンジニアなど何でも屋。 COBOLからReactまで色んなことやります。
sasakki デザイナー
アメリカの大学を卒業後、日本、シンガポールでデザイナーとして活動。
やまかわたかし デザイナー
フロントエンドデザイナー。デザインからHTML / CSS、JSの実装を担当しています。最近はReactやReact Nativeをよく触っています。
Sayaka Osanai デザイナー
Sketchだいすきプロダクトデザイナー。シンプルだけどちょっとかわいいデザインが得意。 好きな食べものは生ハムとお寿司とカレーです。
はらた エンジニア
サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています
こぼり ともろう エンジニア
サーバーサイドエンジニア。SIerを経て2019年7月に入社。日々学習しながらRuby on Railsを使った開発を行っています。
ささい エンジニア
フロントエンドエンジニア WebGLとReactが強みと言えるように頑張ってます。
Damien
WebAR/VRの企画・開発をやっています。森に住んでいます。
ゲスト bagelee
かっきー
まりな
suzuki
miyagi
ogawa
雑食デザイナー。UI/UXデザインやコーディング、時々フロントエンドやってます。最近はARも。
いわもと
デザイナーをしています。 好きな食べ物はラーメンです。
taishi kobari
フロントエンドの開発を主に担当してます。Blitz.js好きです。
kubota shogo
サーバーサイドエンジニア。Ruby on Railsを使った開発を行いつつ月500kmほど走っています!
nishi tomoya
aihara
グラフィックデザイナーから、フロントエンドエンジニアになりました。最近はWebAR/VRの開発や、Blender、Unityを触っています。モノづくりとワンコが好きです。
nagao
SIerを経てアプリのエンジニアに。xR業界に興味があり、unityを使って開発をしたりしています。
Kainuma
サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています
sugimoto
asama
ando
iwasawa ayane
yoko oshimo
異業界からやってきたデザイナー。palanARのUIをメインに担当してます。これからたくさん吸収していきます!