Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,6 @@ vendor/bundle
/yarn-error.log
yarn-debug.log*
.yarn-integrity

# Git worktrees
.worktrees
4 changes: 3 additions & 1 deletion app/models/waiting_list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ class WaitingList < ApplicationRecord
scope :with_notes_and_their_authors, -> { includes(member: { member_notes: :author }) }

def self.add(invitation, auto_rsvp = true)
create(invitation: invitation, auto_rsvp: auto_rsvp)
find_or_create_by(invitation: invitation) do |waiting_list|
waiting_list.auto_rsvp = auto_rsvp
end
end

def self.students(workshop)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
class AddUniqueIndexToWaitingListsInvitationId < ActiveRecord::Migration[8.1]
def up
# Clean up duplicate waiting list entries
duplicate_count = say_with_time "Cleaning up duplicate waiting list entries" do
duplicate_invitation_ids = WaitingList
.group(:invitation_id)
.having('COUNT(*) > 1')
.pluck(:invitation_id)

duplicate_count = duplicate_invitation_ids.count
say "Found #{duplicate_count} invitation_ids with duplicates"

if duplicate_count > 0
# For each duplicate set, keep oldest and delete the rest
duplicate_invitation_ids.each do |invitation_id|
entries = WaitingList
.where(invitation_id: invitation_id)
.order(:created_at)

# Get IDs to delete (all except first/oldest)
ids_to_delete = entries[1..].map(&:id)
deleted_count = ids_to_delete.size

say " Invitation #{invitation_id}: deleting #{deleted_count} duplicate(s), keeping entry ##{entries.first.id}"

# Use delete_all for performance and to avoid callbacks
WaitingList.where(id: ids_to_delete).delete_all
end
end

duplicate_count
end

# Add unique constraint (remove existing non-unique index first if it exists)
say_with_time "Adding unique index on waiting_lists.invitation_id" do
begin
remove_index :waiting_lists, :invitation_id
rescue StandardError => e
say " Note: Could not remove existing index (#{e.message})"
end

add_index :waiting_lists, :invitation_id, unique: true
end
end

def down
begin
remove_index :waiting_lists, :invitation_id
rescue StandardError => e
say "Could not remove index: #{e.message}"
end
# Note: Cannot restore deleted duplicate entries
end
end
Loading