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


177
178
179
180
181
# File 'app/models/group.rb', line 177

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


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

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

#corporationObject


191
192
193
194
195
# File 'app/models/group.rb', line 191

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

#corporation?Boolean

Returns:

  • (Boolean)

200
201
202
# File 'app/models/group.rb', line 200

def corporation?
  kind_of? Corporation
end

#corporation_idObject


196
197
198
# File 'app/models/group.rb', line 196

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

#deceasedObject


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

def deceased
  find_deceased_members_parent_group
end

#delete_cacheObject


44
45
46
47
# File 'app/models/group.rb', line 44

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



187
188
189
# File 'app/models/group.rb', line 187

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.


135
136
137
138
139
140
# File 'app/models/group.rb', line 135

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

#eventsObject

Events



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

def events
  self.descendant_events
end

#extensive_nameObject


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

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
    name + ": " + parent_groups.first.parent_groups.first.name
  elsif super.present?
    super
  else
    name
  end
end

#find_deceased_members_parent_groupObject


216
217
218
# File 'app/models/group.rb', line 216

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

#group_of_groups=(add_the_flag) ⇒ Object


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

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)

107
108
109
# File 'app/models/group.rb', line 107

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.


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

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


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

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.

165
166
167
168
# File 'app/models/group.rb', line 165

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.


64
65
66
# File 'app/models/group.rb', line 64

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

#name_with_corporationObject


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

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.


56
57
58
# File 'app/models/group.rb', line 56

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

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

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

#upcoming_eventsObject


154
155
156
# File 'app/models/group.rb', line 154

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