Skip to content

Commit

Permalink
chore: created base migration and schema for students records and cla…
Browse files Browse the repository at this point in the history
…sses relationship

- created `students_records_classes` table
- created `StudentsRecords.StudentRecordClassRelationship` schema
- added classes fields to `StudentRecord` schema
  • Loading branch information
endoooo committed Dec 12, 2024
1 parent bd87191 commit 3ca9ae3
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 1 deletion.
28 changes: 28 additions & 0 deletions lib/lanttern/students_records/student_record.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ defmodule Lanttern.StudentsRecords.StudentRecord do

import LantternWeb.Gettext

alias Lanttern.StudentsRecords.StudentRecordClassRelationship
alias Lanttern.StudentsRecords.StudentRecordRelationship
alias Lanttern.StudentsRecords.StudentRecordStatus
alias Lanttern.StudentsRecords.StudentRecordType
alias Lanttern.Schools.Class
alias Lanttern.Schools.School
alias Lanttern.Schools.Student

Expand All @@ -21,6 +23,9 @@ defmodule Lanttern.StudentsRecords.StudentRecord do
date: Date.t(),
time: Time.t(),
students: [Student.t()],
students_ids: [pos_integer()],
classes: [Class.t()],
classes_ids: [pos_integer()],
school_id: pos_integer(),
school: School.t(),
status_id: pos_integer(),
Expand All @@ -37,17 +42,21 @@ defmodule Lanttern.StudentsRecords.StudentRecord do
field :date, :date
field :time, :time
field :students_ids, {:array, :id}, virtual: true
field :classes_ids, {:array, :id}, virtual: true

belongs_to :school, School
belongs_to :status, StudentRecordStatus
belongs_to :type, StudentRecordType

has_many :students_relationships, StudentRecordRelationship, on_replace: :delete
has_many :classes_relationships, StudentRecordClassRelationship, on_replace: :delete

many_to_many :students, Student,
join_through: "students_students_records",
preload_order: [asc: :name]

many_to_many :classes, Class, join_through: "students_records_classes"

timestamps()
end

Expand All @@ -60,12 +69,14 @@ defmodule Lanttern.StudentsRecords.StudentRecord do
:date,
:time,
:students_ids,
:classes_ids,
:school_id,
:type_id,
:status_id
])
|> validate_required([:description, :date, :school_id, :type_id, :status_id])
|> cast_and_validate_students()
|> cast_classes()
end

def cast_and_validate_students(changeset) do
Expand Down Expand Up @@ -96,4 +107,21 @@ defmodule Lanttern.StudentsRecords.StudentRecord do
end

defp cast_students(changeset, _), do: changeset

defp cast_classes(changeset) do
case get_change(changeset, :classes_ids) do
classes_ids when is_list(classes_ids) ->
school_id = get_field(changeset, :school_id)

classes_relationships_params =
Enum.map(classes_ids, &%{class_id: &1, school_id: school_id})

changeset
|> put_change(:classes_relationships, classes_relationships_params)
|> cast_assoc(:classes_relationships)

_ ->
changeset
end
end
end
22 changes: 22 additions & 0 deletions lib/lanttern/students_records/student_record_class_relationship.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
defmodule Lanttern.StudentsRecords.StudentRecordClassRelationship do
@moduledoc """
The `StudentRecordClassRelationship` schema (join table)
"""

use Ecto.Schema
import Ecto.Changeset

@primary_key false
schema "students_records_classes" do
field :student_record_id, :id, primary_key: true
field :class_id, :id, primary_key: true
field :school_id, :id
end

@doc false
def changeset(student_record_class_relationship, attrs) do
student_record_class_relationship
|> cast(attrs, [:class_id, :student_record_id, :school_id])
|> validate_required([:class_id, :student_record_id, :school_id])
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ defmodule Lanttern.StudentsRecords.StudentRecordRelationship do
@doc false
def changeset(student_record_relationship, attrs) do
student_record_relationship
|> cast(attrs, [:student_id, :student_record_i, :school_id])
|> cast(attrs, [:student_id, :student_record_id, :school_id])
|> validate_required([:student_id, :student_record_id, :school_id])
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
defmodule Lanttern.Repo.Migrations.CreateStudentsRecordsClasses do
use Ecto.Migration

def change do
# creating unique constraints to allow composite foreign keys.
# this guarantees, in the database level, that record and class
# belong to the same school

# removing existing "classes_school_id_index" to prevent unnecessary index
drop index(:classes, [:school_id])
create unique_index(:classes, [:school_id, :id])

create table(:students_records_classes, primary_key: false) do
# in the future we will handle how to cascade class and school deletion to ss records
add :class_id, references(:classes, with: [school_id: :school_id], on_delete: :nothing),
null: false

add :student_record_id,
references(:students_records, with: [school_id: :school_id], on_delete: :delete_all),
null: false

add :school_id, references(:schools, on_delete: :nothing), null: false
end

create index(:students_records_classes, [:class_id])
create unique_index(:students_records_classes, [:student_record_id, :class_id])
end
end

0 comments on commit 3ca9ae3

Please sign in to comment.