Skip to content

Commit 73297e1

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 45c50e5 commit 73297e1

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
@@ -92,9 +92,9 @@ def import_school_moves(changesets, import)
9292
school_move.confirm! if school_move.patient.persisted?
9393
end
9494

95-
SchoolMove.import(
95+
SchoolMove.import!(
9696
importable_school_moves.to_a,
97-
on_duplicate_key_ignore: :all
97+
on_duplicate_key_update: :all
9898
)
9999
end
100100

app/models/class_import.rb

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

80-
SchoolMove.import(school_moves, on_duplicate_key_ignore: true)
80+
SchoolMove.import!(school_moves, on_duplicate_key_ignore: true)
8181

8282
PatientsAgedOutOfSchoolJob.perform_later
8383
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
@@ -175,17 +175,13 @@ def school_move
175175
patient.home_educated != home_educated ||
176176
patient.not_in_team?(team:, academic_year:) ||
177177
patient.archived?(team:)
178-
school_move =
179-
if school
180-
SchoolMove.find_or_initialize_by(patient:, school:)
181-
else
182-
SchoolMove.find_or_initialize_by(patient:, home_educated:, team:)
183-
end
184-
185-
school_move.tap do
186-
it.academic_year = academic_year
187-
it.source = school_move_source
188-
end
178+
school_move = SchoolMove.find_or_initialize_by(patient:)
179+
school_move.assign_from(school:, home_educated:, team:)
180+
school_move.assign_attributes(
181+
academic_year:,
182+
source: school_move_source
183+
)
184+
school_move
189185
end
190186
end
191187
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
@@ -62,17 +62,10 @@ def to_school_move(patient)
6262
if patient.new_record? || patient.school != school ||
6363
patient.home_educated != home_educated ||
6464
patient.not_in_team?(team:, academic_year:) || patient.archived?(team:)
65-
school_move =
66-
if school
67-
SchoolMove.find_or_initialize_by(patient:, school:)
68-
else
69-
SchoolMove.find_or_initialize_by(patient:, home_educated:, team:)
70-
end
71-
72-
school_move.tap do
73-
it.academic_year = academic_year
74-
it.source = school_move_source
75-
end
65+
school_move = SchoolMove.find_or_initialize_by(patient:)
66+
school_move.assign_from(school:, home_educated:, team:)
67+
school_move.assign_attributes(academic_year:, source: school_move_source)
68+
school_move
7669
end
7770
end
7871

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
@@ -770,8 +770,7 @@
770770
t.datetime "created_at", null: false
771771
t.datetime "updated_at", null: false
772772
t.integer "academic_year", null: false
773-
t.index ["patient_id", "home_educated", "team_id"], name: "index_school_moves_on_patient_id_and_home_educated_and_team_id", unique: true
774-
t.index ["patient_id", "school_id"], name: "index_school_moves_on_patient_id_and_school_id", unique: true
773+
t.index ["patient_id"], name: "index_school_moves_on_patient_id", unique: true
775774
t.index ["school_id"], name: "index_school_moves_on_school_id"
776775
t.index ["team_id"], name: "index_school_moves_on_team_id"
777776
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)