Skip to content

Commit 32e85eb

Browse files
committed
Ensure only one school move exists per patient
This updates the indexes on the school move table to ensure that only one school move can exist per patient, and makes it so that when you import a new school move it replaces any that already exist. This is to resolve the current confusing behaviour where accepting a school move deletes any others, so users need to know which order to accept school moves in. Jira-Issue: MAV-1806
1 parent 72c73ca commit 32e85eb

12 files changed

+107
-55
lines changed

app/jobs/commit_patient_changesets_job.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ def import_school_moves(changesets, import)
9090
school_move.confirm! if school_move.patient.persisted?
9191
end
9292

93-
SchoolMove.import(
93+
SchoolMove.import!(
9494
importable_school_moves.to_a,
95-
on_duplicate_key_ignore: :all
95+
on_duplicate_key_update: :all
9696
)
9797
end
9898

app/models/class_import.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def postprocess_rows!
7676
)
7777
end
7878

79-
SchoolMove.import(school_moves, on_duplicate_key_ignore: true)
79+
SchoolMove.import!(school_moves, on_duplicate_key_ignore: true)
8080

8181
PatientsAgedOutOfSchoolJob.perform_later
8282
end

app/models/consent_form.rb

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -443,13 +443,8 @@ def match_with_patient!(patient, current_user:)
443443
patient.school != school || patient.home_educated != home_educated
444444

445445
if school_changed && !patient.deceased? && !patient.invalidated?
446-
school_move =
447-
if school
448-
SchoolMove.find_or_initialize_by(patient:, school:)
449-
else
450-
SchoolMove.find_or_initialize_by(patient:, home_educated:, team:)
451-
end
452-
446+
school_move = SchoolMove.find_or_initialize_by(patient:)
447+
school_move.assign_from(school:, home_educated:, team:)
453448
school_move.update!(academic_year:, source: :parental_consent_form)
454449
end
455450

app/models/patient_changeset.rb

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -174,17 +174,13 @@ def school_move
174174
patient.home_educated != home_educated ||
175175
patient.not_in_team?(team:, academic_year:) ||
176176
patient.archived?(team:)
177-
school_move =
178-
if school
179-
SchoolMove.find_or_initialize_by(patient:, school:)
180-
else
181-
SchoolMove.find_or_initialize_by(patient:, home_educated:, team:)
182-
end
183-
184-
school_move.tap do
185-
it.academic_year = academic_year
186-
it.source = school_move_source
187-
end
177+
school_move = SchoolMove.find_or_initialize_by(patient:)
178+
school_move.assign_from(school:, home_educated:, team:)
179+
school_move.assign_attributes(
180+
academic_year:,
181+
source: school_move_source
182+
)
183+
school_move
188184
end
189185
end
190186
end

app/models/patient_import.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,10 @@ def bulk_import(rows: 100)
130130
end
131131
@school_moves_to_confirm.clear
132132

133-
SchoolMove.import(@school_moves_to_save.to_a, on_duplicate_key_ignore: :all)
133+
SchoolMove.import!(
134+
@school_moves_to_save.to_a,
135+
on_duplicate_key_update: :all
136+
)
134137
@school_moves_to_save.clear
135138
end
136139
end

app/models/patient_import_row.rb

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,10 @@ def to_school_move(patient)
4444
if patient.new_record? || patient.school != school ||
4545
patient.home_educated != home_educated ||
4646
patient.not_in_team?(team:, academic_year:) || patient.archived?(team:)
47-
school_move =
48-
if school
49-
SchoolMove.find_or_initialize_by(patient:, school:)
50-
else
51-
SchoolMove.find_or_initialize_by(patient:, home_educated:, team:)
52-
end
53-
54-
school_move.tap do
55-
it.academic_year = academic_year
56-
it.source = school_move_source
57-
end
47+
school_move = SchoolMove.find_or_initialize_by(patient:)
48+
school_move.assign_from(school:, home_educated:, team:)
49+
school_move.assign_attributes(academic_year:, source: school_move_source)
50+
school_move
5851
end
5952
end
6053

app/models/school_move.rb

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616
#
1717
# Indexes
1818
#
19-
# index_school_moves_on_patient_id_and_home_educated_and_team_id (patient_id,home_educated,team_id) UNIQUE
20-
# index_school_moves_on_patient_id_and_school_id (patient_id,school_id) UNIQUE
21-
# index_school_moves_on_school_id (school_id)
22-
# index_school_moves_on_team_id (team_id)
19+
# index_school_moves_on_patient_id (patient_id) UNIQUE
20+
# index_school_moves_on_school_id (school_id)
21+
# index_school_moves_on_team_id (team_id)
2322
#
2423
# Foreign Keys
2524
#
@@ -49,13 +48,21 @@ class SchoolMove < ApplicationRecord
4948
unless: -> { school.nil? }
5049
}
5150

51+
def assign_from(school:, home_educated:, team:)
52+
if school
53+
assign_attributes(school:, home_educated: nil, team: nil)
54+
else
55+
assign_attributes(school: nil, home_educated:, team:)
56+
end
57+
end
58+
5259
def confirm!(user: nil)
5360
ActiveRecord::Base.transaction do
5461
update_patient!
5562
update_archive_reasons!(user:)
5663
update_sessions!
5764
create_log_entry!(user:)
58-
SchoolMove.where(patient:).destroy_all if persisted?
65+
destroy! if persisted?
5966
end
6067
end
6168

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# frozen_string_literal: true
2+
3+
class MakeSchoolMovesUniqueOnPatient < ActiveRecord::Migration[8.0]
4+
def change
5+
change_table :school_moves, bulk: true do |t|
6+
t.remove_index %i[patient_id home_educated team_id], unique: true
7+
t.remove_index %i[patient_id school_id], unique: true
8+
end
9+
10+
reversible do |dir|
11+
dir.up do
12+
patient_ids_with_multiple_school_moves =
13+
SchoolMove
14+
.group(:patient_id)
15+
.having("COUNT(*) > 1")
16+
.pluck(:patient_id)
17+
18+
patient_ids_with_multiple_school_moves.each do |patient_id|
19+
newest_school_move_id =
20+
SchoolMove.where(patient_id:).order(:created_at).last.id
21+
SchoolMove
22+
.where(patient_id:)
23+
.where.not(id: newest_school_move_id)
24+
.delete_all
25+
end
26+
end
27+
end
28+
29+
add_index :school_moves, :patient_id, unique: true
30+
end
31+
end

db/schema.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -746,8 +746,7 @@
746746
t.datetime "created_at", null: false
747747
t.datetime "updated_at", null: false
748748
t.integer "academic_year", null: false
749-
t.index ["patient_id", "home_educated", "team_id"], name: "index_school_moves_on_patient_id_and_home_educated_and_team_id", unique: true
750-
t.index ["patient_id", "school_id"], name: "index_school_moves_on_patient_id_and_school_id", unique: true
749+
t.index ["patient_id"], name: "index_school_moves_on_patient_id", unique: true
751750
t.index ["school_id"], name: "index_school_moves_on_school_id"
752751
t.index ["team_id"], name: "index_school_moves_on_team_id"
753752
end

spec/factories/school_moves.rb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616
#
1717
# Indexes
1818
#
19-
# index_school_moves_on_patient_id_and_home_educated_and_team_id (patient_id,home_educated,team_id) UNIQUE
20-
# index_school_moves_on_patient_id_and_school_id (patient_id,school_id) UNIQUE
21-
# index_school_moves_on_school_id (school_id)
22-
# index_school_moves_on_team_id (team_id)
19+
# index_school_moves_on_patient_id (patient_id) UNIQUE
20+
# index_school_moves_on_school_id (school_id)
21+
# index_school_moves_on_team_id (team_id)
2322
#
2423
# Foreign Keys
2524
#

0 commit comments

Comments
 (0)