In Prisma, how do I create a many-to-many relationship but one side of the relationship creates unique instances of the other side? - schema

Let's say we are creating an LMS with Students and Exercises.
The Students have many exercises and each exercise has many users...BUT... I want to put a "isComplete Boolean?" on the exercise model and have each student be able to know if they completed that exercise or not.
I know this is a super simple problem, I have been banging my head and cannot for the life of me figure out how to model these!
model Student {
name String
exercises Exercise[]
}
model Exercise {
title String
description String
isComplete Boolean #default(false)
students Student[]
}

That sounds to me like a use case for an explicit many-to-many relation: https://www.prisma.io/docs/concepts/components/prisma-schema/relations/many-to-many-relations#explicit-many-to-many-relations
You can then add this attribute to the third table that connects students with exercises.

Related

How would you decouple a scenario of lessons and students?

Assume you are making a software that manages classes and students.
I'd assume you would have an administrator class, lesson class, and student class.
The administrator class can have various functions such as "get the list of all available lessons" or "get the list of all lessons that a student is enrolled in".
Here's the tricky part.
A lesson can have many students while a student can have many lessons.
Here are some implementations I have thought of:
Lesson class contains list of students and student class contains list of lessons:
Pro: Straightforward, Con: Coupled
Lesson class contains list of students and in order to do "get all lessons a student is enrolled in" the administrator class would first get all lessons and then filter lessons containing that student.
Pro: Not coupled, Con: Inefficient computing
In the administrator class, have the following fields :
HashMap<Lesson, [Student]>
HashMap<Student, [Lesson]>
Pro: Not coupled, Con: Messy
None of them seem satisfying to me. Can I get some feedback on this dilemma? What is the typically accepted design pattern?
I wouldn't have the complete Student object inside Lesson objects and vice versa.
Lesson class contains a Set of studentIds of the subscribed students
Student class contains a Set of lessonIds in which they are subscribed to.
Your Administrator class can use these Ids to map, filter, retrieve lessons, students and their relationships.
Edit:
I have to say, that in a real life scenario where your data would be persisted for example in a relational database, you should have a table Students, a table Lessons and a table StudentsLessons with studentId and lessonId as foreign keys.
This is how I would go about it considering the fact that in future I might need to persist them in the DB.
The relationship between student and lesson is many-to-many and hence you need to setup bi-directional
or unidirectional relationship with these two classes.
Bi-directional - List of lessons in Student class and vice versa
Unidirectional - Either list of lessons in Student or list of
students in Lesson class
For example sake, I am setting unidirectional relationship
class Student {
private List<Lesson> lessions;
// other attributes
}
class Lesson {
// Lesson attributes
}
The Administrator class you are talking about is actually a good candidate for service class because it's providing services
such as "get the list of all available lessons"
For Lesson related queries, I'll create LessonService
class LessonService {
// Get the list of all available lessons
List<Lesson> findAllLessons() {...}
// Get all lessons a student is enrolled in
List<Lession> findAllLessons(Student student) {...}
}
and finally, there would a repository/dao layer that will abstract underlying database.
Your repository could be a simple collection based in-memory or represent the actual database.

Why does GORM use a join table for one-to-many?

From the Grails documentation, by default one-to-many relationships are represented using a join table.
I don't understand why this is desirable. I had little SQL experience before starting to use Hibernate and/or Grails' GORM. It seems like using a foreign key in the 'many'-side table pointing at a row on the 'one'-side table is the way to implement a one-to-many relationship...
Can anyone explain this sort of design decision?
The reason for using an join table for a unidirectional one-to-many relationship is because the many side of the relationship may have many relationships and does not know of those relationships. Perhaps an example is best here:
class Book {
String title
}
class BookStore {
String name
static hasMany = [books: Book]
}
class Library {
String name
static hasMany = [books: Book]
}
In the above domain, a Book has no need to have both the BookStore and Library IDs on it's table. A Book is perfectly valid without either. By using join tables this keeps from polluting the book table with foreign keys.
Keep in mind because this is modeling uni-directional and not bi-directional relationships.

New to Object Oriented Design

I am new to object oriented design. I am looking forward to some tips on how to model the below mentioned requirement using objects.
Requirement: A program has many Students. A program logs in to the application. First page displays a table of all the Students belonging to the program (Table Columns - Id, First name, last name, age, sex, etc. ). The Id is a link. By clicking the Id, the individual student page is displayed. In this page, an individual student related activities can be done - for eg. edit address, change name, add comments etc.
My Solution: Two Classes
Program - Will model a single program, perform all activities related to it and encapsulate all program related db tables.
Student - Will model a single student and perform all activities related to it and encapsulate all student specific db tables.
So far, so good.
In order to fetch details of all students related to a program, from Program object I need to call a method called 'fetch_student_details'.
The Question is where should this method be written? Should it be a Student Class method or Program Class method.
If I write this method in program class, how will the Program class handle it?
(a) First identify the list of student_ids that belong to it and for each id, instantiate a Student Class and get the specific student related information from it. DB: Each instantiated student object will run a query to fetch its information. So 100 students, 100 queries.
OR
(b) Fetch the list of student ids related to the program and fetch the student information directly for all the students. Db: Single query to fetch all the needed information.
In this case, if you can, go for solution (b). Students and Programs, in fact, are two differet entities that can exist independently, and you don't break encapsulation.
With solution (a) you need to pollute Program's interface by adding a method for each possible information that you want to get from the Students.
As final suggestion, if you want to learn OO Design, start by reading the book "Design patterns - Elements of Reusable Object-Oriented Software" by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides (AKA "The gang of four").

Relational Data: entity inheritance approaches. Best practice

There are several approaches how to store entities hierarchy in relation database
For example there is person entity (20 basic attributes), student entity (the same as person but several new specific fields are present), employee (the same as person but some new fields are present) e.t.c.
When you advice to use (and not to use) the following data modeling approaches:
One big table with all possible fields + personType marker field (student or employee)
Table inheritance
One Table with XML field (or maybe another data type) to store all the custom fields
Something else but also relational...
Thank you in advance!
A database models facts, not objects, and each table should model a relatively self-contained set of facts. The consequence of this is that your tables should look something like this:
person { person_id PK, name, dob, ... }
student { person_id PK FK(person.person_id), admission_id, year_started, ... }
employee { person_id PK FK(person.person_id), salary_bracket, ... }
An additional consequence is that a student can also be an employee, which probably models real life closer than an inheritance graph would.
Have a look at the hibernate inheritance mapping docs. There you find three common approaches and a list of pros and cons of each.
If you are using an ORM to implement your classes, the ORM tools you are using will provide you options, generally two options, one class one table or one parent class one table and each table for each children class. I am using XPO from Devexpress.com, one ORM framework. It offers these two options.
If you use ORM, I am afraid there are no other generic options.
Ying

Entity Relationship Model: Ternary Relationships

I am trying to understand why this statement in the book is wrong: "given a C entity, there is at most one related A entity and at most one related B entity".
Is it that it doesn't apply to a specific kind of relationship??
So, if I have an example of a student who is in attendance to a course with a type of subject. The entities are student, attendance, course and subject. Student makes attendance in a room. Also, a student can make attendance for a subject. Does this example apply to the statement?
Thanks for your time.
The author probably means: in a single relationship instance (e.g., student-Bob/course-ABC/attendance123). So there is a single student, a single course and a single attendance record linked in that instance.
Not across all relationship instances in the class (where student Bob could attend many classes over time).