-
Notifications
You must be signed in to change notification settings - Fork 398
Expand file tree
/
Copy pathrole_adapter.rb
More file actions
139 lines (119 loc) · 5.6 KB
/
role_adapter.rb
File metadata and controls
139 lines (119 loc) · 5.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
require 'rolify/adapters/base'
module Rolify
module Adapter
class RoleAdapter < RoleAdapterBase
def where(relation, *args)
conditions = build_conditions(relation, args)
relation.any_of(*conditions)
end
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 }
elsif args[:resource].present?
{:resource_type => args[:resource].class.name, :resource_id => args[:resource].id}
else
{}
end
conditions.merge!(:name => args[:name])
conditions = wrap_conditions ? { role_table => conditions } : conditions
relation.where(conditions)
end
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
return relation.find_all { |role| role.name == args[:name].to_s } if args[:resource] == :any
relation.find_all do |role|
(role.name == args[:name].to_s && role.resource_type == nil && role.resource_id == nil) ||
(role.name == args[:name].to_s && role.resource_type == resource_type && role.resource_id == nil) ||
(role.name == args[:name].to_s && role.resource_type == resource_type && role.resource_id == resource_id)
end
end
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
relation.find_all do |role|
role.resource_id == resource_id && role.resource_type == resource_type && role.name == args[:name].to_s
end
end
def find_or_create_by(role_name, resource_type = nil, resource_id = nil)
self.role_class.find_or_create_by(:name => role_name,
:resource_type => resource_type,
:resource_id => resource_id)
end
def add(relation, role)
relation.roles << role
end
def remove(relation, role_name, resource = nil)
#roles = { :name => role_name }
#roles.merge!({:resource_type => (resource.is_a?(Class) ? resource.to_s : resource.class.name)}) if resource
#roles.merge!({ :resource_id => resource.id }) if resource && !resource.is_a?(Class)
#roles_to_remove = relation.roles.where(roles)
#roles_to_remove.each do |role|
# # Deletion in n-n relations is unreliable. Sometimes it works, sometimes not.
# # So, this does not work all the time: `relation.roles.delete(role)`
# # @see http://stackoverflow.com/questions/9132596/rails3-mongoid-many-to-many-relation-and-delete-operation
# # We instead remove ids from the Role object and the relation object.
# relation.role_ids.delete(role.id)
# role.send((user_class.to_s.underscore + '_ids').to_sym).delete(relation.id)
#
# role.destroy if role.send(user_class.to_s.tableize.to_sym).empty?
#end
cond = { :name => role_name }
cond[:resource_type] = (resource.is_a?(Class) ? resource.to_s : resource.class.name) if resource
cond[:resource_id] = resource.id if resource && !resource.is_a?(Class)
roles = relation.roles.where(cond)
roles.each do |role|
relation.roles.delete(role)
role.send(ActiveSupport::Inflector.demodulize(user_class).tableize.to_sym).delete(relation)
if Rolify.remove_role_if_empty && role.send(ActiveSupport::Inflector.demodulize(user_class).tableize.to_sym).empty?
role.destroy
end
end if roles
roles
end
def exists?(relation, column)
relation.where(column.to_sym.ne => nil)
end
def scope(relation, conditions, strict)
query = strict ? where_strict(role_class, conditions) : where(role_class, conditions)
roles = query.map { |role| role.id }
return [] if roles.size.zero?
query = relation.any_in(:role_ids => roles)
query
end
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)
conditions = []
args.each do |arg|
if arg.is_a? Hash
query = build_query(arg[:name], arg[:resource])
elsif arg.is_a?(String) || arg.is_a?(Symbol)
query = build_query(arg)
else
raise ArgumentError, "Invalid argument type: only hash or string or symbol allowed"
end
conditions += query
end
conditions
end
def build_query(role, resource = nil)
return [{ :name => role }] if resource == :any
query = [{ :name => role, :resource_type => nil, :resource_id => nil }]
if resource
query << { :name => role, :resource_type => (resource.is_a?(Class) ? resource.to_s : resource.class.name), :resource_id => nil }
if !resource.is_a? Class
query << { :name => role, :resource_type => resource.class.name, :resource_id => resource.id }
end
end
query
end
end
end
end