Class: Group

Inherits:
ActiveRecord::Base show all
Includes:
ActiveModel::ForbiddenAttributesProtection, GroupMixins::Corporations, GroupMixins::Developers, GroupMixins::Everyone, GroupMixins::Guests, GroupMixins::HiddenUsers, GroupMixins::Import, GroupMixins::Memberships, GroupMixins::Officers, GroupMixins::Roles
Defined in:
app/models/group.rb

Overview

This class represents a user group. Besides users, groups may have sub-groups as children. One group may have several parent-groups. Therefore, the relations between groups, users, etc. is stored using the DAG model, which is implemented by the ‘is_structureable` method.

Direct Known Subclasses

Corporation, ListExportGroup, StatusGroup

Instance Method Summary collapse

Methods inherited from ActiveRecord::Base

#readonly?

Instance Method Details

#cached_members_postal_addresses_created_atObject



179
180
181
182
183
# File 'app/models/group.rb', line 179

def cached_members_postal_addresses_created_at
  cached do
    members.collect { |user| user.cache_created_at(:address_label) || Time.zone.now }.min
  end
end

#child_workflowsObject



144
145
146
# File 'app/models/group.rb', line 144

def child_workflows
 self.descendant_workflows.where( :dag_links => { direct: true } )
end

#corporationObject



193
194
195
196
197
# File 'app/models/group.rb', line 193

def corporation
  cached do
    Corporation.find corporation_id if corporation_id
  end
end

#corporation?Boolean

Returns:

  • (Boolean)


202
203
204
# File 'app/models/group.rb', line 202

def corporation?
  kind_of? Corporation
end

#corporation_idObject



198
199
200
# File 'app/models/group.rb', line 198

def corporation_id
  (([self.id] + ancestor_group_ids) & Corporation.pluck(:id)).first
end

#deceasedObject



221
222
223
# File 'app/models/group.rb', line 221

def deceased
  find_deceased_members_parent_group
end

#delete_cacheObject



46
47
48
49
# File 'app/models/group.rb', line 46

def delete_cache
  super
  ancestor_groups(true).each { |g| g.delete_cached(:leaf_groups); g.delete_cached(:status_groups) }
end

#descendant_groups_by_name(descendant_group_name) ⇒ Object

Groups




189
190
191
# File 'app/models/group.rb', line 189

def descendant_groups_by_name( descendant_group_name )
  self.descendant_groups.where( :name => descendant_group_name )
end

#descendant_workflowsObject

These methods override the standard methods, which are usual ActiveRecord associations methods created by the acts-as-dag gem (github.com/resgraph/acts-as-dag/blob/master/lib/dag/dag.rb). But since the Workflow in the main application inherits from WorkflowKit::Workflow and single table inheritance and polymorphic associations do not always work together as expected in rails, as can be seen here stackoverflow.com/questions/9628610/why-polymorphic-association-doesnt-work-for-sti-if-type-column-of-the-polymorph, we have to override these methods.

ActiveRecord associations require ‘WorkflowKit::Workflow’ to be stored in the database’s type column, but by asking for the ‘child_workflows` we want to get òbjects of the `Workflow` type, not `WorkflowKit::Workflow`, since Workflow objects may have additional methods, added by the main application.



137
138
139
140
141
142
# File 'app/models/group.rb', line 137

def descendant_workflows
  Workflow
    .joins( :links_as_descendant )
    .where( :dag_links => { :ancestor_type => "Group", :ancestor_id => self.id } )
    .uniq
end

#eventsObject

Events




152
153
154
# File 'app/models/group.rb', line 152

def events
  self.descendant_events
end

#extensive_nameObject



70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'app/models/group.rb', line 70

def extensive_name
  if has_flag? :attendees
    name + (parent_events.first ? ": " + parent_events.first.name : '')
  elsif has_flag? :contact_people
    name + (parent_events.first ? ": " + parent_events.first.name : '')
  elsif has_flag?(:admins_parent) && parent_groups.first.parent_groups.first
    name + ": " + parent_groups.first.parent_groups.first.name
  elsif super.present?
    super
  else
    name
  end
end

#find_deceased_members_parent_groupObject



218
219
220
# File 'app/models/group.rb', line 218

def find_deceased_members_parent_group
  self.descendant_groups.where(name: ["Verstorbene", "Deceased"]).limit(1).first
end

#group_of_groups=(add_the_flag) ⇒ Object



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

def group_of_groups=(add_the_flag)
  add_the_flag ? add_flag(:group_of_groups) : remove_flag(:group_of_groups)
end

#group_of_groups?Boolean

Mark this group of groups, i.e. the primary members of the group are groups, not users. This does not effect the DAG structure, but may affect the way the group is displayed.

Returns:

  • (Boolean)


109
110
111
# File 'app/models/group.rb', line 109

def group_of_groups?
  has_flag? :group_of_groups
end

#leaf_groupsObject

This returns all sub-groups of the corporation that have no sub-groups of their ownes except for officer groups. This is needed for the selection of status groups.



210
211
212
213
214
215
216
# File 'app/models/group.rb', line 210

def leaf_groups
  cached do
    self.descendant_groups.order('id').includes(:flags).select do |group|
      group.has_no_subgroups_other_than_the_officers_parent? and not group.is_officers_group?
    end
  end
end

#members_postal_addressesObject



171
172
173
174
175
176
177
178
# File 'app/models/group.rb', line 171

def members_postal_addresses
  cached do
    members
      .collect { |user| user.address_label }
      .sort_by { |address_label| (not address_label.country_code == 'DE').to_s + address_label.country_code.to_s + address_label.postal_code.to_s }
      # .collect { |address_label| address_label.to_s }
  end
end

#members_to_pdf(options = {sender: '', book_rate: false}) ⇒ Object

Adress Labels (PDF) options:

- sender:      Sender line including sender address.
- book_rate:   Whether the "Büchersendung"/"Envois à taxe réduite" badge
               is to be printed.


167
168
169
170
# File 'app/models/group.rb', line 167

def members_to_pdf(options = {sender: '', book_rate: false})
  timestamp = cached_members_postal_addresses_created_at || Time.zone.now
  AddressLabelsPdf.new(members_postal_addresses, title: self.title, updated_at: timestamp, **options).render
end

#nameObject

The name of the group. If there is a translation for that group name, e.g. for a generic group name like ‘admins’, use the translation.



66
67
68
# File 'app/models/group.rb', line 66

def name
  I18n.t( super.to_sym, default: super ) if super.present?
end

#name_with_corporationObject



84
85
86
87
88
89
90
# File 'app/models/group.rb', line 84

def name_with_corporation
  if self.corporation && self.corporation.id != self.id
    "#{self.name} (#{self.corporation.name})"
  else
    self.name
  end
end

#titleObject

The title of the group, i.e. a kind of caption, e.g. used in the <title> tag of the webpage. By default, this returns just the name of the group. But this may be changed in the main application.



58
59
60
# File 'app/models/group.rb', line 58

def title
  self.name
end

#to_paramObject

This sets the format of the Group urls to be

example.com/groups/24-planeswalkers

rather than just

example.com/groups/24


100
101
102
# File 'app/models/group.rb', line 100

def to_param
  "#{id} #{title}".parameterize
end

#upcoming_eventsObject



156
157
158
# File 'app/models/group.rb', line 156

def upcoming_events
  self.events.upcoming.order('start_at')
end