Skip to content

Commit 277f8b4

Browse files
committed
Replace registration status patient session foreign key
This replaces the foreign key association between registration statuses and patient sessions to instead link directly to the patient. This is needed as we eventually want to replace the PatientSession model and to do that we need to make sure all foreign keys to it have been replaced. The functionality should be the same before and after. Jira-Issue: MAV-1821
1 parent e87d5e7 commit 277f8b4

13 files changed

+156
-83
lines changed

app/lib/status_generator/registration.rb

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# frozen_string_literal: true
22

33
class StatusGenerator::Registration
4-
def initialize(patient_session:, session_attendance:, vaccination_records:)
5-
@patient_session = patient_session
4+
def initialize(patient:, session:, session_attendance:, vaccination_records:)
5+
@patient = patient
6+
@session = session
67
@session_attendance = session_attendance
78
@vaccination_records = vaccination_records
89
end
@@ -21,17 +22,18 @@ def status
2122

2223
private
2324

24-
attr_reader :patient_session, :session_attendance, :vaccination_records
25+
attr_reader :patient, :session, :session_attendance, :vaccination_records
2526

26-
def academic_year = patient_session.session.academic_year
27+
delegate :academic_year, to: :session
2728

2829
def status_should_be_completed?
29-
patient_session.programmes.all? do |programme|
30-
vaccination_records.any? do
31-
it.programme_id == programme.id &&
32-
it.session_id == patient_session.session_id
30+
session
31+
.programmes_for(patient:, academic_year:)
32+
.all? do |programme|
33+
vaccination_records.any? do
34+
it.programme_id == programme.id && it.session_id == session.id
35+
end
3336
end
34-
end
3537
end
3638

3739
def status_should_be_attending?

app/lib/status_updater.rb

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,22 @@ def update_consent_statuses!
5050

5151
def update_registration_statuses!
5252
Patient::RegistrationStatus.import!(
53-
%i[patient_session_id],
54-
registration_statuses_to_import,
53+
%i[patient_id session_id],
54+
patient_session_statuses_to_import,
5555
on_duplicate_key_ignore: true
5656
)
5757

5858
Patient::RegistrationStatus
59-
.where(patient_session_id: patient_sessions.select(:id))
59+
.where(
60+
patient: patient_sessions.select(:patient_id),
61+
session: patient_sessions.select(:session_id)
62+
)
6063
.includes(
64+
:patient,
6165
:session_attendances,
6266
:session_date,
6367
:vaccination_records,
64-
patient_session: {
65-
session: :programmes
66-
}
68+
session: :programmes
6769
)
6870
.find_in_batches(batch_size: 10_000) do |batch|
6971
batch.each(&:assign_status)
@@ -167,23 +169,24 @@ def patient_session_statuses_to_import
167169
patient_sessions
168170
.joins(:patient, :session)
169171
.pluck(
170-
:id,
171-
:"session.location_id",
172-
:"session.academic_year",
172+
:"patients.id",
173+
:"sessions.id",
174+
:"sessions.location_id",
175+
:"sessions.academic_year",
173176
:"patients.birth_academic_year"
174177
)
175-
.flat_map do |patient_session_id, location_id, academic_year, birth_academic_year|
178+
.filter_map do |patient_id, session_id, location_id, academic_year, birth_academic_year|
176179
year_group = birth_academic_year.to_year_group(academic_year:)
177180

178-
programme_ids_per_location_id_and_year_group
179-
.fetch(location_id, {})
180-
.fetch(year_group, [])
181-
.map { [patient_session_id, it] }
182-
end
183-
end
181+
if programme_ids_per_location_id_and_year_group
182+
.fetch(location_id, {})
183+
.fetch(year_group, [])
184+
.empty?
185+
next
186+
end
184187

185-
def registration_statuses_to_import
186-
patient_session_statuses_to_import.map { [it.first] }.uniq
188+
[patient_id, session_id]
189+
end
187190
end
188191

189192
def programme_ids_per_year_group

app/models/patient.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class Patient < ApplicationRecord
7272
has_many :patient_sessions
7373
has_many :pds_search_results
7474
has_many :pre_screenings
75+
has_many :registration_statuses
7576
has_many :school_move_log_entries
7677
has_many :school_moves
7778
has_many :session_attendances

app/models/patient/registration_status.rb

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,26 @@
44
#
55
# Table name: patient_registration_statuses
66
#
7-
# id :bigint not null, primary key
8-
# status :integer default("unknown"), not null
9-
# patient_session_id :bigint not null
7+
# id :bigint not null, primary key
8+
# status :integer default("unknown"), not null
9+
# patient_id :bigint not null
10+
# session_id :bigint not null
1011
#
1112
# Indexes
1213
#
13-
# index_patient_registration_statuses_on_patient_session_id (patient_session_id) UNIQUE
14-
# index_patient_registration_statuses_on_status (status)
14+
# idx_on_patient_id_session_id_2ff02d8889 (patient_id,session_id) UNIQUE
15+
# index_patient_registration_statuses_on_patient_id (patient_id)
16+
# index_patient_registration_statuses_on_session_id (session_id)
17+
# index_patient_registration_statuses_on_status (status)
1518
#
1619
# Foreign Keys
1720
#
18-
# fk_rails_... (patient_session_id => patient_sessions.id) ON DELETE => cascade
21+
# fk_rails_... (patient_id => patients.id) ON DELETE => cascade
22+
# fk_rails_... (session_id => sessions.id) ON DELETE => cascade
1923
#
2024
class Patient::RegistrationStatus < ApplicationRecord
21-
belongs_to :patient_session
22-
23-
has_one :patient, through: :patient_session
24-
has_one :session, through: :patient_session
25+
belongs_to :patient
26+
belongs_to :session
2527

2628
has_many :vaccination_records,
2729
-> { kept.order(performed_at: :desc) },
@@ -49,7 +51,8 @@ def assign_status
4951
def generator
5052
@generator ||=
5153
StatusGenerator::Registration.new(
52-
patient_session:,
54+
patient:,
55+
session:,
5356
session_attendance:,
5457
vaccination_records:
5558
)

app/models/patient_session.rb

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ class PatientSession < ApplicationRecord
4444
belongs_to :patient
4545
belongs_to :session
4646

47-
has_one :registration_status, class_name: "Patient::RegistrationStatus"
48-
4947
has_one :location, through: :session
5048
has_one :subteam, through: :session
5149
has_one :team, through: :session
@@ -66,6 +64,12 @@ class PatientSession < ApplicationRecord
6664
-> { where(patient_id: it.patient_id) },
6765
through: :session
6866

67+
has_one :registration_status,
68+
-> { where(session_id: it.session_id) },
69+
through: :patient,
70+
source: :registration_statuses,
71+
class_name: "Patient::RegistrationStatus"
72+
6973
has_many :session_attendances,
7074
-> { where(patient_id: it.patient_id) },
7175
through: :session
@@ -188,7 +192,8 @@ class PatientSession < ApplicationRecord
188192
->(status) do
189193
where(
190194
Patient::RegistrationStatus
191-
.where("patient_session_id = patient_sessions.id")
195+
.where("patient_id = patient_sessions.patient_id")
196+
.where("session_id = patient_sessions.session_id")
192197
.where(status:)
193198
.arel
194199
.exists
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# frozen_string_literal: true
2+
3+
class RemovePatientSessionFromPatientRegistrationStatuses < ActiveRecord::Migration[
4+
8.0
5+
]
6+
def up
7+
change_table :patient_registration_statuses, bulk: true do |t|
8+
t.references :patient, foreign_key: { on_delete: :cascade }
9+
t.references :session, foreign_key: { on_delete: :cascade }
10+
t.index %i[patient_id session_id], unique: true
11+
end
12+
13+
Patient::RegistrationStatus.find_each do |registration_status|
14+
patient_session =
15+
PatientSession.find(registration_status.patient_session_id)
16+
patient_id = patient_session.patient_id
17+
session_id = patient_session.session_id
18+
registration_status.update_columns(patient_id:, session_id:)
19+
end
20+
21+
change_table :patient_registration_statuses, bulk: true do |t|
22+
t.change_null :patient_id, false
23+
t.change_null :session_id, false
24+
t.remove_references :patient_session
25+
end
26+
end
27+
28+
def down
29+
change_table :patient_registration_statuses, bulk: true do |t|
30+
t.references :patient_session, foreign_key: { on_delete: :cascade }
31+
t.index :patient_session_id, unique: true
32+
end
33+
34+
Patient::RegistrationStatus.find_each do |registration_status|
35+
patient_id = registration_status.patient_id
36+
session_id = registration_status.session_id
37+
patient_session = PatientSession.find_by!(patient_id:, session_id:)
38+
registration_status.update_column(:patient_session_id, patient_session.id)
39+
end
40+
41+
change_table :patient_registration_statuses, bulk: true do |t|
42+
t.change_null :patient_session_id, false
43+
t.remove_references :patient, :session
44+
end
45+
end
46+
end

db/schema.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -619,9 +619,12 @@
619619
end
620620

621621
create_table "patient_registration_statuses", force: :cascade do |t|
622-
t.bigint "patient_session_id", null: false
623622
t.integer "status", default: 0, null: false
624-
t.index ["patient_session_id"], name: "index_patient_registration_statuses_on_patient_session_id", unique: true
623+
t.bigint "patient_id", null: false
624+
t.bigint "session_id", null: false
625+
t.index ["patient_id", "session_id"], name: "idx_on_patient_id_session_id_2ff02d8889", unique: true
626+
t.index ["patient_id"], name: "index_patient_registration_statuses_on_patient_id"
627+
t.index ["session_id"], name: "index_patient_registration_statuses_on_session_id"
625628
t.index ["status"], name: "index_patient_registration_statuses_on_status"
626629
end
627630

@@ -1123,7 +1126,8 @@
11231126
add_foreign_key "patient_changesets", "patients"
11241127
add_foreign_key "patient_consent_statuses", "patients", on_delete: :cascade
11251128
add_foreign_key "patient_consent_statuses", "programmes"
1126-
add_foreign_key "patient_registration_statuses", "patient_sessions", on_delete: :cascade
1129+
add_foreign_key "patient_registration_statuses", "patients", on_delete: :cascade
1130+
add_foreign_key "patient_registration_statuses", "sessions", on_delete: :cascade
11271131
add_foreign_key "patient_sessions", "patients"
11281132
add_foreign_key "patient_sessions", "sessions"
11291133
add_foreign_key "patient_specific_directions", "patients"

spec/factories/patient_registration_statuses.rb

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,27 @@
44
#
55
# Table name: patient_registration_statuses
66
#
7-
# id :bigint not null, primary key
8-
# status :integer default("unknown"), not null
9-
# patient_session_id :bigint not null
7+
# id :bigint not null, primary key
8+
# status :integer default("unknown"), not null
9+
# patient_id :bigint not null
10+
# session_id :bigint not null
1011
#
1112
# Indexes
1213
#
13-
# index_patient_registration_statuses_on_patient_session_id (patient_session_id) UNIQUE
14-
# index_patient_registration_statuses_on_status (status)
14+
# idx_on_patient_id_session_id_2ff02d8889 (patient_id,session_id) UNIQUE
15+
# index_patient_registration_statuses_on_patient_id (patient_id)
16+
# index_patient_registration_statuses_on_session_id (session_id)
17+
# index_patient_registration_statuses_on_status (status)
1518
#
1619
# Foreign Keys
1720
#
18-
# fk_rails_... (patient_session_id => patient_sessions.id) ON DELETE => cascade
21+
# fk_rails_... (patient_id => patients.id) ON DELETE => cascade
22+
# fk_rails_... (session_id => sessions.id) ON DELETE => cascade
1923
#
2024
FactoryBot.define do
2125
factory :patient_registration_status, class: "Patient::RegistrationStatus" do
22-
patient_session
23-
26+
patient
27+
session
2428
traits_for_enum :status
2529
end
2630
end

spec/factories/patient_sessions.rb

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,27 +43,29 @@
4343
end
4444

4545
trait :unknown_attendance do
46-
registration_status do
47-
association(:patient_registration_status, patient_session: instance)
48-
end
49-
end
50-
51-
trait :in_attendance do
52-
registration_status do
53-
association(
46+
after(:create) do |patient_session|
47+
create(
5448
:patient_registration_status,
55-
:attending,
56-
patient_session: instance
49+
patient: patient_session.patient,
50+
session: patient_session.session
5751
)
5852
end
53+
end
5954

55+
trait :in_attendance do
6056
after(:create) do |patient_session|
6157
create(
6258
:session_attendance,
6359
:present,
6460
patient: patient_session.patient,
6561
session: patient_session.session
6662
)
63+
create(
64+
:patient_registration_status,
65+
:attending,
66+
patient: patient_session.patient,
67+
session: patient_session.session
68+
)
6769
end
6870
end
6971

spec/factories/patients.rb

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,7 @@
125125

126126
after(:create) do |patient, evaluator|
127127
if evaluator.session
128-
patient_session =
129-
patient.patient_sessions.find_or_create_by!(
130-
session: evaluator.session
131-
)
128+
PatientSession.find_or_create_by!(patient:, session: evaluator.session)
132129

133130
if evaluator.in_attendance
134131
create(
@@ -137,7 +134,12 @@
137134
patient:,
138135
session: evaluator.session
139136
)
140-
create(:patient_registration_status, :attending, patient_session:)
137+
create(
138+
:patient_registration_status,
139+
:attending,
140+
patient:,
141+
session: evaluator.session
142+
)
141143
end
142144
end
143145
end

0 commit comments

Comments
 (0)