Skip to content

Commit 1decfc7

Browse files
committed
Replace session attendance patient session foreign key
This replaces the foreign key association between session attendances 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-1820
1 parent a7060f5 commit 1decfc7

18 files changed

+200
-98
lines changed

app/controllers/patient_sessions/session_attendances_controller.rb

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,13 @@ def update
4343

4444
def set_session_attendance
4545
@session_attendance =
46-
authorize @patient_session
47-
.session_attendances
48-
.includes(:patient, :session_date)
49-
.find_or_initialize_by(session_date: @session_date)
46+
authorize(
47+
@patient
48+
.session_attendances
49+
.includes(:patient, :session_date)
50+
.find_or_initialize_by(session_date: @session_date)
51+
.tap { it.patient_session = @patient_session }
52+
)
5053
end
5154

5255
def session_attendance_params

app/lib/generate/vaccination_records.rb

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,20 @@ def create_vaccinations
2323
vaccination_records = []
2424

2525
random_patient_sessions.each do |patient_session|
26-
patient_session_id = patient_session.id
27-
session_date_ids = patient_session.session.session_dates.pluck(:id)
28-
29-
unless SessionAttendance.exists?(
30-
patient_session_id:,
31-
session_date_id: session_date_ids
26+
patient = patient_session.patient
27+
session = patient_session.session
28+
29+
unless SessionAttendance.joins(:session_date).exists?(
30+
patient:,
31+
session_date: {
32+
session:
33+
}
3234
)
3335
session_attendances << FactoryBot.build(
3436
:session_attendance,
3537
:present,
36-
patient_session:
38+
patient:,
39+
session:
3740
)
3841
end
3942

app/models/patient.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class Patient < ApplicationRecord
6565
has_many :consent_notifications
6666
has_many :consent_statuses
6767
has_many :consents
68+
has_many :gillick_assessments
6869
has_many :notes
6970
has_many :notify_log_entries
7071
has_many :parent_relationships, -> { order(:created_at) }
@@ -73,16 +74,15 @@ class Patient < ApplicationRecord
7374
has_many :pre_screenings
7475
has_many :school_move_log_entries
7576
has_many :school_moves
77+
has_many :session_attendances
7678
has_many :session_notifications
7779
has_many :triage_statuses
7880
has_many :triages
7981
has_many :vaccination_records, -> { kept }
8082
has_many :vaccination_statuses
8183

82-
has_many :gillick_assessments
8384
has_many :parents, through: :parent_relationships
8485
has_many :patient_specific_directions
85-
has_many :session_attendances, through: :patient_sessions
8686
has_many :sessions, through: :patient_sessions
8787
has_many :teams, -> { distinct }, through: :sessions
8888

app/models/patient_session.rb

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

47-
has_many :session_attendances, dependent: :destroy
4847
has_one :registration_status
4948

5049
has_one :location, through: :session
@@ -67,6 +66,10 @@ class PatientSession < ApplicationRecord
6766
-> { where(patient_id: it.patient_id) },
6867
through: :session
6968

69+
has_many :session_attendances,
70+
-> { where(patient_id: it.patient_id) },
71+
through: :session
72+
7073
has_many :session_notifications,
7174
-> { where(session_id: it.session_id) },
7275
through: :patient
@@ -286,9 +289,11 @@ def programmes = session.programmes_for(patient:, academic_year:)
286289

287290
def todays_attendance
288291
if (session_date = session.session_dates.today.first)
289-
session_attendances.includes(:session_date).find_or_initialize_by(
290-
session_date:
291-
)
292+
patient
293+
.session_attendances
294+
.includes(:session_date)
295+
.find_or_initialize_by(session_date:)
296+
.tap { it.patient_session = self }
292297
end
293298
end
294299

app/models/patient_session/registration_status.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,14 @@ class PatientSession::RegistrationStatus < ApplicationRecord
2727
through: :patient
2828

2929
has_one :session_attendance,
30-
-> { today },
31-
through: :patient_session,
30+
-> do
31+
today.where(
32+
session_dates: {
33+
session_id: it.patient_session.session_id
34+
}
35+
)
36+
end,
37+
through: :patient,
3238
source: :session_attendances
3339

3440
enum :status,

app/models/session.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class Session < ApplicationRecord
5555
has_many :programmes, through: :session_programmes
5656
has_many :gillick_assessments, through: :session_dates
5757
has_many :patients, through: :patient_sessions
58+
has_many :session_attendances, through: :session_dates
5859
has_many :vaccines, through: :programmes
5960

6061
has_many :location_programme_year_groups,

app/models/session_attendance.rb

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,36 @@
44
#
55
# Table name: session_attendances
66
#
7-
# id :bigint not null, primary key
8-
# attending :boolean not null
9-
# created_at :datetime not null
10-
# updated_at :datetime not null
11-
# patient_session_id :bigint not null
12-
# session_date_id :bigint not null
7+
# id :bigint not null, primary key
8+
# attending :boolean not null
9+
# created_at :datetime not null
10+
# updated_at :datetime not null
11+
# patient_id :bigint not null
12+
# session_date_id :bigint not null
1313
#
1414
# Indexes
1515
#
16-
# idx_on_patient_session_id_session_date_id_be8bd21ddf (patient_session_id,session_date_id) UNIQUE
17-
# index_session_attendances_on_session_date_id (session_date_id)
16+
# index_session_attendances_on_patient_id (patient_id)
17+
# index_session_attendances_on_session_date_id (session_date_id)
1818
#
1919
# Foreign Keys
2020
#
21-
# fk_rails_... (patient_session_id => patient_sessions.id)
21+
# fk_rails_... (patient_id => patients.id)
2222
# fk_rails_... (session_date_id => session_dates.id)
2323
#
2424
class SessionAttendance < ApplicationRecord
25-
audited associated_with: :patient_session
25+
audited associated_with: :patient
2626

27-
belongs_to :patient_session
27+
belongs_to :patient
2828
belongs_to :session_date
2929

30-
has_one :session, through: :patient_session
31-
has_one :patient, through: :patient_session
30+
has_one :session, through: :session_date
3231
has_one :location, through: :session
3332

3433
scope :today, -> { joins(:session_date).merge(SessionDate.today) }
34+
35+
# This is a bit of a hack, but it allows the SessionAttendancePolicy class
36+
# to have access to the patient session which has already been fetched from
37+
# the database elsewhere.
38+
attr_accessor :patient_session
3539
end
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# frozen_string_literal: true
2+
3+
class RemovePatientSessionFromSessionAttendances < ActiveRecord::Migration[8.0]
4+
def up
5+
change_table :session_attendances, bulk: true do |t|
6+
t.references :patient, foreign_key: true
7+
end
8+
9+
SessionAttendance.find_each do |session_attendance|
10+
patient_session =
11+
PatientSession.find(session_attendance.patient_session_id)
12+
patient_id = patient_session.patient_id
13+
session_attendance.update_column(:patient_id, patient_id)
14+
end
15+
16+
change_table :session_attendances, bulk: true do |t|
17+
t.change_null :patient_id, false
18+
t.remove_references :patient_session
19+
end
20+
end
21+
22+
def down
23+
add_reference :session_attendances, :patient_session
24+
25+
SessionAttendance.find_each do |session_attendance|
26+
session_id =
27+
SessionDate.find(session_attendance.session_date_id).session_id
28+
patient_session =
29+
PatientSession.find_by!(
30+
patient_id: session_attendance.patient_id,
31+
session_id:
32+
)
33+
session_attendance.update_column(:patient_session_id, patient_session.id)
34+
end
35+
36+
change_table :gillick_assessments, bulk: true do |t|
37+
t.change_null :patient_session_id, false
38+
t.remove_references :patient
39+
end
40+
end
41+
end

db/schema.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema[8.0].define(version: 2025_08_21_124416) do
13+
ActiveRecord::Schema[8.0].define(version: 2025_08_21_135954) do
1414
# These are extensions that must be enabled in order to support this database
1515
enable_extension "pg_catalog.plpgsql"
1616
enable_extension "pg_trgm"
@@ -780,12 +780,12 @@
780780
end
781781

782782
create_table "session_attendances", force: :cascade do |t|
783-
t.bigint "patient_session_id", null: false
784783
t.bigint "session_date_id", null: false
785784
t.boolean "attending", null: false
786785
t.datetime "created_at", null: false
787786
t.datetime "updated_at", null: false
788-
t.index ["patient_session_id", "session_date_id"], name: "idx_on_patient_session_id_session_date_id_be8bd21ddf", unique: true
787+
t.bigint "patient_id", null: false
788+
t.index ["patient_id"], name: "index_session_attendances_on_patient_id"
789789
t.index ["session_date_id"], name: "index_session_attendances_on_session_date_id"
790790
end
791791

@@ -1085,7 +1085,7 @@
10851085
add_foreign_key "school_moves", "locations", column: "school_id"
10861086
add_foreign_key "school_moves", "patients"
10871087
add_foreign_key "school_moves", "teams"
1088-
add_foreign_key "session_attendances", "patient_sessions"
1088+
add_foreign_key "session_attendances", "patients"
10891089
add_foreign_key "session_attendances", "session_dates"
10901090
add_foreign_key "session_dates", "sessions"
10911091
add_foreign_key "session_notifications", "patients"

spec/factories/patient_sessions.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,22 @@
5252
end
5353

5454
trait :in_attendance do
55-
session_attendances do
56-
[association(:session_attendance, :present, patient_session: instance)]
57-
end
5855
registration_status do
5956
association(
6057
:patient_session_registration_status,
6158
:attending,
6259
patient_session: instance
6360
)
6461
end
62+
63+
after(:create) do |patient_session|
64+
create(
65+
:session_attendance,
66+
:present,
67+
patient: patient_session.patient,
68+
session: patient_session.session
69+
)
70+
end
6571
end
6672

6773
trait :added_to_session

0 commit comments

Comments
 (0)