Browse Source

Add random subgrouping

Maarten van den Berg 7 years ago
parent
commit
e0d094833a
1 changed files with 35 additions and 0 deletions
  1. 35 0
      app/models/activity.rb

+ 35 - 0
app/models/activity.rb

@@ -183,7 +183,42 @@ class Activity < ApplicationRecord
183 183
     self.delay(run_at: self.reminder_at).send_reminder
184 184
   end
185 185
 
186
+  # Assign a subgroup to all attending participants without one.
187
+  def assign_subgroups!
188
+    # Sanity check: we need subgroups to divide into.
189
+    return unless self.subgroups.any?
190
+
191
+    # Get participants in random order
192
+    ps = self
193
+      .participants
194
+      .where(attending: true)
195
+      .where(subgroup: nil)
196
+      .to_a
197
+
198
+    ps.shuffle!
199
+
200
+    # Get groups, link to participant count
201
+    groups = self
202
+      .subgroups
203
+      .where(is_assignable: true)
204
+      .to_a
205
+      .map { |sg| [sg.participants.count, sg] }
206
+
207
+    ps.each do |p|
208
+      # Sort groups so the group with the least participants gets the following participant
209
+      groups.sort!
210
+
211
+      # Assign participant to group with least members
212
+      p.subgroup = groups.first.second
213
+      p.save
214
+
215
+      # Update the group's position in the list, will sort when next participant is processed.
216
+      groups.first[0] += 1
217
+    end
218
+  end
219
+
186 220
   private
221
+
187 222
   # Assert that the deadline for participants to change the deadline, if any,
188 223
   # is set before the event starts.
189 224
   def deadline_before_start