Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 11 additions & 25 deletions lib/rolify/finders.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,22 @@ def without_role(role_name, resource = nil)
end

def with_all_roles(*args)
users = []
parse_args(args, users) do |users_to_add|
users = users_to_add if users.empty?
users &= users_to_add
return [] if users.empty?
end
users
# Build a single query with all role conditions
role_count = args.length
self.adapter.scope(self, args, false)
.group("#{table_name}.#{primary_key}")
.having("COUNT(DISTINCT #{role_table}.id) = ?", role_count)
end

def with_any_role(*args)
users = []
parse_args(args, users) do |users_to_add|
users += users_to_add
end
users.uniq
# Build a single query with OR conditions for all roles
self.adapter.scope(self, args, false).distinct
end
end

private

def parse_args(args, users, &block)
args.each do |arg|
if arg.is_a? Hash
users_to_add = self.with_role(arg[:name], arg[:resource])
elsif arg.is_a?(String) || arg.is_a?(Symbol)
users_to_add = self.with_role(arg)
else
raise ArgumentError, "Invalid argument type: only hash or string or symbol allowed"
end
block.call(users_to_add)
end

def role_table
self.role_class.table_name
end
end
23 changes: 15 additions & 8 deletions lib/rolify/role.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,23 @@ def has_strict_cached_role?(role_name, resource = nil)
end

def has_all_roles?(*args)
args.each do |arg|
if arg.is_a? Hash
return false if !self.has_role?(arg[:name], arg[:resource])
elsif arg.is_a?(String) || arg.is_a?(Symbol)
return false if !self.has_role?(arg)
else
raise ArgumentError, "Invalid argument type: only hash or string or symbol allowed"
if new_record?
# For new records, check in memory
args.all? do |arg|
if arg.is_a? Hash
self.has_role?(arg[:name], arg[:resource])
elsif arg.is_a?(String) || arg.is_a?(Symbol)
self.has_role?(arg)
else
raise ArgumentError, "Invalid argument type: only hash or string or symbol allowed"
end
end
else
# For persisted records, use a single query
# Count how many of the specified roles the user has
role_count = args.length
self.class.adapter.where(self.roles, *args).distinct.count == role_count
end
true
end

def has_any_role?(*args)
Expand Down