@@ -63,7 +63,8 @@ def revoke_role!(role_name, resource)
63
63
private
64
64
65
65
def accessible_roles_for ( resource , inheritnce )
66
- return Monarchy . role_class . none unless resource . hierarchy
66
+ return Monarchy . role_class . none unless resource . persisted?
67
+
67
68
accessible_roles = if inheritnce
68
69
resource_and_inheritance_roles ( resource )
69
70
else
@@ -75,29 +76,32 @@ def accessible_roles_for(resource, inheritnce)
75
76
end
76
77
77
78
def resource_and_inheritance_roles ( resource )
78
- hierarchy_ids = resource . hierarchy . ancestors . select ( :id )
79
-
80
79
Monarchy . role_class . where ( id :
81
80
Monarchy . role_class
82
81
. joins ( 'INNER JOIN monarchy_members_roles ON monarchy_roles.id = monarchy_members_roles.role_id' )
83
82
. joins ( "INNER JOIN (SELECT id, hierarchy_id FROM monarchy_members WHERE user_id = #{ id } ) as " \
84
83
'monarchy_members ON monarchy_members.id = monarchy_members_roles.member_id' )
85
84
. where ( 'monarchy_roles.inherited' : 't' )
86
- . where ( 'monarchy_members.hierarchy_id' : hierarchy_ids )
85
+ . where ( 'monarchy_members.hierarchy_id' : ancestors_for ( resource ) . select ( :id ) )
87
86
. select ( 'monarchy_roles.inherited_role_id' ) )
88
87
. union ( resource_roles ( resource ) )
89
88
end
90
89
91
90
def resource_roles ( resource )
91
+ resource_hierarchy = hierarchies_for ( resource ) . select ( :id )
92
+
93
+ user_memberships = Monarchy . member_class
94
+ . where ( hierarchy_id : resource_hierarchy , user_id : id )
95
+ . select ( :id , :hierarchy_id ) . to_sql
96
+
92
97
Monarchy . role_class
93
98
. joins ( 'INNER JOIN monarchy_members_roles ON monarchy_roles.id = monarchy_members_roles.role_id' )
94
- . joins ( 'INNER JOIN (SELECT id, hierarchy_id FROM monarchy_members WHERE ' \
95
- "hierarchy_id = #{ resource . hierarchy . id } AND user_id = #{ id } ) as monarchy_members ON " \
99
+ . joins ( "INNER JOIN (#{ user_memberships } ) as monarchy_members ON " \
96
100
'monarchy_members.id = monarchy_members_roles.member_id' )
97
101
end
98
102
99
103
def descendant_role ( resource )
100
- descendants = resource . hierarchy . descendants
104
+ descendants = descendants_for ( resource )
101
105
children_access = members_for ( descendants ) . present?
102
106
103
107
if children_access
@@ -148,12 +152,38 @@ def grant_or_create_member(role_names, resource)
148
152
member
149
153
end
150
154
155
+ def inherited_default_role
156
+ @inherited_default_role ||= Monarchy . role_class . find_by ( name : Monarchy . configuration . inherited_default_role )
157
+ end
158
+
159
+ # TODO: Make these methods public in related interfaces
160
+
151
161
def members_for ( hierarchies )
152
162
Monarchy . member_class . where ( hierarchy : hierarchies , user_id : id )
153
163
end
154
164
155
- def inherited_default_role
156
- @inherited_default_role ||= Monarchy . role_class . find_by ( name : Monarchy . configuration . inherited_default_role )
165
+ def hierarchies_for ( resources )
166
+ Monarchy . hierarchy_class . where ( resource : resources )
167
+ end
168
+
169
+ def descendants_for ( resources )
170
+ resources_hierarchies = hierarchies_for ( resources ) . select ( :id )
171
+
172
+ Monarchy . hierarchy_class
173
+ . joins ( 'INNER JOIN monarchy_hierarchy_hierarchies ON ' \
174
+ 'monarchy_hierarchies.id = monarchy_hierarchy_hierarchies.descendant_id' )
175
+ . where ( monarchy_hierarchy_hierarchies : { ancestor_id : resources_hierarchies } )
176
+ . where . not ( monarchy_hierarchies : { id : resources_hierarchies } )
177
+ end
178
+
179
+ def ancestors_for ( resources )
180
+ resources_hierarchies = hierarchies_for ( resources ) . select ( :id )
181
+
182
+ Monarchy . hierarchy_class
183
+ . joins ( 'INNER JOIN monarchy_hierarchy_hierarchies ON ' \
184
+ 'monarchy_hierarchies.id = monarchy_hierarchy_hierarchies.ancestor_id' )
185
+ . where ( monarchy_hierarchy_hierarchies : { descendant_id : resources_hierarchies } )
186
+ . where . not ( monarchy_hierarchies : { id : resources_hierarchies } )
157
187
end
158
188
end
159
189
end
0 commit comments