Module: StructureableMixins::Roles

Extended by:
ActiveSupport::Concern
Included in:
Structureable::StructureableInstanceMethods
Defined in:
app/models/structureable_mixins/roles.rb

Overview

This module extends the Structureable models by methods for the interaction with roles. For example, a structureable object is being equipped with a ‘admins` association that lists all (direct) admin users of the object. To make a user an admin of a structureable object, you may call `object.admins << user`.

This module is included by ‘include StructureableMixins::Roles`.

The helper methods used in the module are defined in ‘StructureableMixins::HasSpecialGroups`.

Instance Method Summary collapse

Instance Method Details

#adminsObject



207
208
209
# File 'app/models/structureable_mixins/roles.rb', line 207

def admins
  find_or_create_admins_parent_group.try( :descendant_users ) || []
end

#admins_of_ancestor_groupsObject



223
224
225
# File 'app/models/structureable_mixins/roles.rb', line 223

def admins_of_ancestor_groups
  cached { ancestor_groups.collect { |ancestor| ancestor.find_admins }.flatten }
end

#admins_of_ancestorsObject



219
220
221
# File 'app/models/structureable_mixins/roles.rb', line 219

def admins_of_ancestors
  cached { ancestors.collect { |ancestor| ancestor.find_admins }.flatten }
end

#admins_of_self_and_ancestorsObject



227
228
229
# File 'app/models/structureable_mixins/roles.rb', line 227

def admins_of_self_and_ancestors
  cached { find_admins + admins_of_ancestors }
end

#admins_parentObject



199
200
201
# File 'app/models/structureable_mixins/roles.rb', line 199

def admins_parent
  find_or_create_admins_parent_group
end

#admins_parent!Object



203
204
205
# File 'app/models/structureable_mixins/roles.rb', line 203

def admins_parent!
  find_admins_parent_group || raise('special group :admins_parent does not exist.')
end

#create_admins_parent_groupObject



184
185
186
187
# File 'app/models/structureable_mixins/roles.rb', line 184

def create_admins_parent_group
  delete_cached(:find_admins)
  create_special_group(:admins_parent, parent_element: find_or_create_officers_parent_group )
end

#create_main_admins_parent_groupObject



255
256
257
# File 'app/models/structureable_mixins/roles.rb', line 255

def create_main_admins_parent_group
  create_special_group(:main_admins_parent, parent_element: find_or_create_admins_parent_group )
end

#create_officers_parent_groupObject



76
77
78
79
80
81
# File 'app/models/structureable_mixins/roles.rb', line 76

def create_officers_parent_group
  if self.ancestor_groups(true).find_all_by_flag(:officers_parent).count == 0 and not self.has_flag?(:officers_parent)
    # Do not allow officer cascades.
    create_special_group(:officers_parent)
  end
end

#delete_cacheObject



31
32
33
34
# File 'app/models/structureable_mixins/roles.rb', line 31

def delete_cache
  super
  delete_caches_concerning_roles
end

#delete_caches_concerning_rolesObject



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'app/models/structureable_mixins/roles.rb', line 36

def delete_caches_concerning_roles
  if is_a? Group
    # For an admins_parent, this is called recursively until the original group
    # is reached.
    #
    #   group
    #     |---- officers_parent
    #                |------------ admins_parent
    #                |------------ some officer group
    #
    if has_flag?(:officers_parent) || has_flag?(:admins_parent)
      parent_groups.each do |group| 
        group.delete_cache
        if group.descendants.count > 0
          bulk_delete_cached :admins_of_ancestors, group.descendants
          bulk_delete_cached :admins_of_self_and_ancestors, group.descendants
          bulk_delete_cached "*officers*", group.descendants
        end
      end
    end
  end
end

#direct_officersObject



112
113
114
# File 'app/models/structureable_mixins/roles.rb', line 112

def direct_officers
  self.find_officers_parent_group.try(:descendant_users) || []
end

#fill_cacheObject



18
19
20
21
22
23
24
25
26
27
28
29
# File 'app/models/structureable_mixins/roles.rb', line 18

def fill_cache
  super
  if respond_to?(:child_groups) # TODO: Refactor this. It should be possible to find the admins for a user.
    find_admins
    admins_of_ancestors
    admins_of_self_and_ancestors
    officers_of_self_and_parent_groups
    officers_groups_of_self_and_descendant_groups
    officers_of_self_and_ancestors
    officers_of_self_and_ancestor_groups
  end
end

#find_adminsObject



211
212
213
214
215
216
217
# File 'app/models/structureable_mixins/roles.rb', line 211

def find_admins
  cached do
    if respond_to? :child_groups
      find_admins_parent_group.try( :descendant_users ) 
    end || []
  end || []
end

#find_admins_parent_groupObject

Admins

Each structureable object may have admins (users), which are collected in the ‘admins_parent` special group of the structureable object, which is a subgroup of the officers_parent subgroup of the structureable object.

my_structureable
        |----------- officers_parent
                           |----------- admins_parent

One can access or assign the admins of the structureable object by calling:

my_structureable.admins          # => Array of users
my_structureable.admins << user


180
181
182
# File 'app/models/structureable_mixins/roles.rb', line 180

def find_admins_parent_group
  find_special_group(:admins_parent, parent_element: find_officers_parent_group )
end

#find_main_admins_parent_groupObject

Main Admins

Main admins are also admins. But they have more rights and responsibilities. For example, they may edit the critical properties of the objects they administrate.

Since main admins are also admins, the special group structure looks like this:

my_structureable
        |----------- officers_parent
                           |----------- admins_parent
                                            |---------- main_admins_parent

One can access or assign the main admins of the structureable object by calling:

my_structureable.main_admins          # => Array of users
my_structureable.main_admins << user


251
252
253
# File 'app/models/structureable_mixins/roles.rb', line 251

def find_main_admins_parent_group
  find_special_group(:main_admins_parent, parent_element: find_admins_parent_group)
end

#find_officersObject



130
131
132
133
134
135
136
# File 'app/models/structureable_mixins/roles.rb', line 130

def find_officers
  cached do
    if respond_to? :child_groups
      find_officers_parent_group.try(:descendant_users) 
    end || []
  end
end

#find_officers_groupsObject

This method lists all officer groups of the group, i.e. all subgroups of the officers_parent group.



105
106
107
# File 'app/models/structureable_mixins/roles.rb', line 105

def find_officers_groups
  self.find_officers_parent_group.try(:descendant_groups) || []
end

#find_officers_parent_groupObject

Officers

Each structureable object may have officers, e.g. the president of the organization. Officers are collected in a subgroup with the flag :officers_parent. This officers_parent group may also have subgroups. But, of course, the officers_parent group must not have another officers_parent subgroup.

Calling ‘some_structureable_object.officers` lists all officer users of the structureable itself **and of the sub groups** of the structureable object.



72
73
74
# File 'app/models/structureable_mixins/roles.rb', line 72

def find_officers_parent_group
  find_special_group(:officers_parent)
end

#find_officers_parent_groups_of_self_and_of_descendant_groupsObject

This method returns all officer_parent groups of the structureable object itself and of the descendant groups of the structureable object.



98
99
100
# File 'app/models/structureable_mixins/roles.rb', line 98

def find_officers_parent_groups_of_self_and_of_descendant_groups
  [self.find_officers_parent_group] + self.descendant_groups.find_all_by_flag(:officers_parent) - [nil]
end

#find_or_create_admins_parent_groupObject



189
190
191
192
193
194
195
196
197
# File 'app/models/structureable_mixins/roles.rb', line 189

def find_or_create_admins_parent_group
    find_special_group(:admins_parent, parent_element: find_or_create_officers_parent_group) or
    begin
      delete_cached(:find_admins)
      create_special_group(:admins_parent, parent_element: find_or_create_officers_parent_group)
    rescue
      nil
    end
end

#find_or_create_main_admins_parent_groupObject



259
260
261
# File 'app/models/structureable_mixins/roles.rb', line 259

def find_or_create_main_admins_parent_group
  find_or_create_special_group(:main_admins_parent, parent_element: find_or_create_admins_parent_group )
end

#find_or_create_officers_parent_groupObject



83
84
85
# File 'app/models/structureable_mixins/roles.rb', line 83

def find_or_create_officers_parent_group
  find_officers_parent_group || create_officers_parent_group
end

#main_adminsObject



271
272
273
# File 'app/models/structureable_mixins/roles.rb', line 271

def main_admins
  main_admins_parent.descendant_users
end

#main_admins_parentObject



263
264
265
# File 'app/models/structureable_mixins/roles.rb', line 263

def main_admins_parent
  find_or_create_main_admins_parent_group
end

#main_admins_parent!Object



267
268
269
# File 'app/models/structureable_mixins/roles.rb', line 267

def main_admins_parent!
  find_main_admins_parent_group || raise('special group :main_admins_parent does not exist.')
end

#officersObject

This method returns all officer users, as well all of this group as of its subgroups.



156
157
158
159
160
# File 'app/models/structureable_mixins/roles.rb', line 156

def officers
  self.find_officers_parent_groups_of_self_and_of_descendant_groups.collect do |officers_parent|
    officers_parent.descendant_users
  end.flatten.uniq
end

#officers_groupsObject



108
109
110
# File 'app/models/structureable_mixins/roles.rb', line 108

def officers_groups
  self.officers_parent.descendant_groups
end

#officers_groups_of_self_and_descendant_groupsObject



122
123
124
125
126
127
128
# File 'app/models/structureable_mixins/roles.rb', line 122

def officers_groups_of_self_and_descendant_groups
  cached do
    self.find_officers_parent_groups_of_self_and_of_descendant_groups.collect do |officers_parent|
      officers_parent.descendant_groups
    end.flatten.uniq
  end
end

#officers_of_ancestor_groupsObject



142
143
144
# File 'app/models/structureable_mixins/roles.rb', line 142

def officers_of_ancestor_groups
  cached { ancestor_groups.collect { |ancestor| ancestor.find_officers }.flatten }
end

#officers_of_ancestorsObject



138
139
140
# File 'app/models/structureable_mixins/roles.rb', line 138

def officers_of_ancestors
  cached { ancestors.collect { |ancestor| ancestor.find_officers }.flatten }
end

#officers_of_self_and_ancestor_groupsObject



150
151
152
# File 'app/models/structureable_mixins/roles.rb', line 150

def officers_of_self_and_ancestor_groups
  cached { find_officers + officers_of_ancestor_groups }
end

#officers_of_self_and_ancestorsObject



146
147
148
# File 'app/models/structureable_mixins/roles.rb', line 146

def officers_of_self_and_ancestors
  cached { find_officers + officers_of_ancestors }
end

#officers_of_self_and_parent_groupsObject



116
117
118
119
120
# File 'app/models/structureable_mixins/roles.rb', line 116

def officers_of_self_and_parent_groups
  cached do
    direct_officers + (parent_groups.collect { |parent_group| parent_group.direct_officers }.flatten)
  end
end

#officers_parentObject



87
88
89
# File 'app/models/structureable_mixins/roles.rb', line 87

def officers_parent
  find_or_create_officers_parent_group
end

#officers_parent!Object



91
92
93
# File 'app/models/structureable_mixins/roles.rb', line 91

def officers_parent!
  find_officers_parent_group || raise('special group :officers_parent does not exist.')
end