banken
素敵な権限管理gem bankenさん。
使い勝手がよくて大好きです。作ってくれたkyudenさんありがとうございます!
Userの権限管理をもっと楽に書きたい....
社内システム構築時に、Userの権限によってアクセスできる機能を制限したい。
Userモデルはこんな感じ
user.rb
class User < ActiveRecord::Base
enum permission: {
guest: 0, #ゲストアカウント
staff: 1, #一般スタッフ
customer_support: 2, #カスタマーサポート
manager: 3, #管理職
developer: 4 # 開発者
}
end
権限パターンがふえてくると、こう書くのは冗長...
loyalties/post_loyalty.rb
class PostLoyalty < ApplicationLoyalty
def index
end
def update?
user == developer? || user == record.user?
end
# ↓こいつ冗長だな....。
def destroy?
user == developer? || user == customer_support? || user == record.user?
end
end
こうしてみた
同僚から、
before_action :set_user, only: [:new, :create]
みたいにかければ良いんじゃない?
before_actionのソースコードを読んだがメタプロすぎて良くわからなかったので、自分で書いた。
loyalties/application_loyalty.rb
class ApplicationLoyalty
attr_reader :user, :record
def initialize(user, record)
@user = user
@record = record
end
# ... 省略...
def permit_user(**option)
raise ArgumentError.new("Invalid hash Size for argument. 1 is acceptable size.") unless option.keys.size == 1
key = option.keys.first
permissions = [].append(option[key]).flatten
case key #妥協のハードコーディング。もっといい方法思いついたら教えてください....。
when :only
return permissions.include?(user.permission.to_sym)
when :except
return !permissions.include?(user.permission.to_sym)
else
raise ArgumentError.new('Invald key for argument "option". :only and :except is acceptable key')
end
end
end
loyalties/post_loyalty.rb
class PostLoyalty < ApplicationLoyalty
def index
end
def update?
permit_user only: :developer || user == record.user?
end
def destroy?
permit_user only: [:developer, :customer_support, :manager] || user == record.user?
end
end
マサカリください!
もっとよいコードにしていきたい....。
ここダメじゃね?
こう拡張したときどうすんの?
こう書いたほうがいいんじゃない?
みたいなマサカリおまちしております!