Skip to content

Commit

Permalink
Implement proper STI support in Rolify
Browse files Browse the repository at this point in the history
  • Loading branch information
bopm committed Nov 28, 2024
1 parent 55261dc commit 7e42eae
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 13 deletions.
19 changes: 12 additions & 7 deletions lib/rolify/adapters/active_record/role_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ def where_strict(relation, args)
wrap_conditions = relation.name != role_class.name

conditions = if args[:resource].is_a?(Class)
{:resource_type => args[:resource].to_s, :resource_id => nil }
{:resource_type => resource_base_class(args[:resource]), :resource_id => nil }
elsif args[:resource].present?
{:resource_type => args[:resource].class.name, :resource_id => args[:resource].id}
{:resource_type => resource_base_class(args[:resource]), :resource_id => args[:resource].id}
else
{}
end
Expand All @@ -27,7 +27,7 @@ def where_strict(relation, args)

def find_cached(relation, args)
resource_id = (args[:resource].nil? || args[:resource].is_a?(Class) || args[:resource] == :any) ? nil : args[:resource].id
resource_type = args[:resource].is_a?(Class) ? args[:resource].to_s : args[:resource].class.name
resource_type = resource_base_class(args[:resource])

return relation.find_all { |role| role.name == args[:name].to_s } if args[:resource] == :any

Expand All @@ -40,7 +40,7 @@ def find_cached(relation, args)

def find_cached_strict(relation, args)
resource_id = (args[:resource].nil? || args[:resource].is_a?(Class)) ? nil : args[:resource].id
resource_type = args[:resource].is_a?(Class) ? args[:resource].to_s : args[:resource].class.name
resource_type = resource_base_class(args[:resource])

relation.find_all do |role|
role.resource_id == resource_id && role.resource_type == resource_type && role.name == args[:name].to_s
Expand All @@ -57,7 +57,7 @@ def add(relation, role)

def remove(relation, role_name, resource = nil)
cond = { :name => role_name }
cond[:resource_type] = (resource.is_a?(Class) ? resource.to_s : resource.class.name) if resource
cond[:resource_type] = resource_base_class(resource) if resource
cond[:resource_id] = resource.id if resource && !resource.is_a?(Class)
roles = relation.roles.where(cond)
if roles
Expand All @@ -83,6 +83,11 @@ def all_except(user, excluded_obj)
user.where.not(user.primary_key => excluded_obj)
end

def resource_base_class(resource)
resource_class = resource.is_a?(Class) ? resource : resource.class
resource_class.polymorphic_name
end

private

def build_conditions(relation, args)
Expand Down Expand Up @@ -110,10 +115,10 @@ def build_query(role, resource = nil)
if resource
query.insert(0, "(")
query += " OR ((#{role_table}.name = ?) AND (#{role_table}.resource_type = ?) AND (#{role_table}.resource_id IS NULL))"
values << role << (resource.is_a?(Class) ? resource.to_s : resource.class.name)
values << role << resource_base_class(resource)
if !resource.is_a? Class
query += " OR ((#{role_table}.name = ?) AND (#{role_table}.resource_type = ?) AND (#{role_table}.resource_id = ?))"
values << role << resource.class.name << resource.id
values << role << resource_base_class(resource) << resource.id
end
query += ")"
end
Expand Down
4 changes: 4 additions & 0 deletions lib/rolify/adapters/mongoid/role_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ def all_except(user, excluded_obj)
user.not_in(_id: excluded_obj.to_a)
end

def resource_base_class(resource)
resource.is_a?(Class) ? resource.to_s : resource.class.name
end

private

def build_conditions(relation, args)
Expand Down
2 changes: 1 addition & 1 deletion lib/rolify/dynamic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module Rolify
module Dynamic
def define_dynamic_method(role_name, resource)
class_eval do
class_eval do
define_method("is_#{role_name}?".to_sym) do
has_role?("#{role_name}")
end if !method_defined?("is_#{role_name}?".to_sym) && self.adapter.where_strict(self.role_class, name: role_name).exists?
Expand Down
8 changes: 4 additions & 4 deletions lib/rolify/resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ def with_role(role_name, user = nil)
user ? self.resource_adapter.in(resources, user, role_name) : resources
end
alias :with_roles :with_role
alias :find_as :with_role
alias :find_as :with_role
alias :find_multiple_as :with_role


def without_role(role_name, user = nil)
self.resource_adapter.all_except(self, self.find_as(role_name, user))
end
alias :without_roles :without_role
alias :except_as :without_role
alias :except_multiple_as :without_role
alias :except_as :without_role
alias :except_multiple_as :without_role



Expand All @@ -38,7 +38,7 @@ def applied_roles(children = true)
end



end

def applied_roles
Expand Down
2 changes: 1 addition & 1 deletion lib/rolify/role.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def self.included(base)

def add_role(role_name, resource = nil)
role = self.class.adapter.find_or_create_by(role_name.to_s,
(resource.is_a?(Class) ? resource.to_s : resource.class.name if resource),
(self.class.adapter.resource_base_class(resource) if resource),
(resource.id if resource && !resource.is_a?(Class)))

if !roles.include?(role)
Expand Down

0 comments on commit 7e42eae

Please sign in to comment.