Skip to content

Instantly share code, notes, and snippets.

@davidderus
Last active October 26, 2016 11:47
Show Gist options
  • Save davidderus/94da6286b1046e7b0954134becc76209 to your computer and use it in GitHub Desktop.
Save davidderus/94da6286b1046e7b0954134becc76209 to your computer and use it in GitHub Desktop.
Non-Standard ApplicationPolicy for Pundit
# Handling Application rights thanks to roles
#
# A direct adaptation of http://through-voidness.blogspot.fr/2013/10/advanced-rails-4-authorization-with.html
# but much more performance-wise
class ApplicationPolicy
attr_reader :user, :record
def initialize(user, record)
raise Pundit::NotAuthorizedError, 'Must be signed in.' unless user
@user = user
@record = record
end
##############################################################
# Globalizing policies handling based on the role activities #
##############################################################
# @return [Array] list of all users allowed activities
def user_activities
@user.roles.pluck(:activities).flatten.uniq
end
# @param [Symbol] method Method to check in class
# @return [String] A combination of model and method
# @note We allow only Class or Symbol, nothing else, to do things like `authorize :dashboard` or `authorize Product`
def inferred_activity(method)
record_class = (@record.class == Class || @record.class == Symbol) ? @record.to_s : @record.class.name
"#{record_class.downcase}:#{method}"
end
# @param [String] name method name
# @param [Object] args method args
def method_missing(name, *args)
method_name = name.to_s
if method_name[-1..-1] == '?'
user_activities.include?(inferred_activity(method_name[0..-2]))
else
super
end
end
##########################
# Keeping some shortcuts #
##########################
# Just a shortcut for create?
def new?
create?
end
# Just a shortcut for edit?
def edit?
update?
end
##################
# Scope handling #
##################
def scope
Pundit.policy_scope!(user, record.class)
end
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
scope
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment