Rails Can Can Canで権限管理 とてもgood!
CanCanCanという権限管理できるgemを利用してみる。
WEBの業務アプリで権限といえば、必要ないものはない!と言えるくらい大切なものです。
参考サイト 1000万以上のダウンロード すごい!
cancancan | RubyGems.org | your community gem host
本家サイト
GitHub - CanCanCommunity/cancancan: The authorization Gem for Ruby on Rails.
gemのインストール
gem 'cancancan', '~> 2.3'
1. Abilitiesのモデルをcancanを利用して作ります。
このクラスが大切になります。 モデルで管理するので安心です。
rails g cancan:ability
生成された、Abilityモデルで定義していきます。
alias_actionで、railsのコントローラーに記載するアクションを決定します。
alias_action :index,:create, :show, :update, :destroy, to: :crud でそれぞれのメソッドがクラッドできるということです。更新、削除等
class Ability include CanCan::Ability def initialize(user) # Define abilities for the passed in user here. For example: //ここでアクションを記載 alias_action :index,:create, :show, :update, :destroy, to: :crud user ||= User.new # guest user (not logged in) if user.company_admin? can :crud, [User,Category], {company_id: user.company_id} else can [:update, :show], User, {company_id: user.company_id, id: user.id} end
ちなみに||= は左辺が未定義、または偽ならば、右辺を代入するという意味
Swiftの ?? に似ている。
userが未定義ならuserを作成しなさいの意味
user ||= User.new
user ||= User.new # guest user (not logged in)
もしログインしていなければ、カラユーザーを作成して判定用に用いる。
ログインしていなくて、アドレス叩く人もいるかも知れない。 saveしていないので、関係ないユーザーは作成されない。
if user.company_admin?
Userテーブルのcompany_admin カラムが真ならば
can :crud, [User,Category], {company_id: user.company_id}
そのユーザーは,User,CategoryテーブルのCRUDができます。 Userモデルのcompany_idカラムが user.company_idと等しいものは。 という意味になります。
ここでcanメソッドの定義を見てみましょう
canは2つの引数を取ります。
第一引数は権限を設定しようとする、アクションです。
defでコントローラーに定義するやつですね。
第2引数は、それを設定しようとする、モデルになります。
can :update, Article
Articleモデルのupdateメソッドに権限設定するということですね。
引数に配列を渡すこともできます。
can [:update, :destroy], [Article, Comment]
そこにアクセス許可できるものを更に追加する場合は、条件のハッシュを渡せます。
それが上記の記載したコードになります。
{company_id: user.company_id}
これは、company_id が現在ログインしているuserのcompany_idが同じものという条件を追加しています。
つまり同じ会社のuserしか見れないということですね。 他の会社の情報が見れたら問題です。
あとは、load_and_authorize_resource メソッドを適用するコントローラーに記載します。
これで先程Abilityモデルで定義した内容がそのコントローラーに適用されます。
class UsersController < ApplicationController before_action :set_user, only: [:show, :edit, :update] before_action :sign_in_auth, only: [:show, :edit, :update] //ここがcan can load_and_authorize_resource
上記のbefore_action :sign_in_auth, only: [:show, :edit, :update]メソッドでは、毎回コントローラーで表示する度に、関数をセットしていて 非常に危ない持ち方をしていた。