Ability to jump "through" one model to another on M:N relationships
See original GitHub issueProblem
Once again this idea is inspired by Ruby on Rails. 😉 ActiveRecord (the ORM library that ships with Rails) has the concept of a “has many through” relationship. That is, one record has many associated records through another record inbetween.
For example, let’s say you have a Car
which gets regular Service
. The record of that car getting a service is handled by the Maintenance
model, which records which car, which service, the date it was performed, and maybe the employee who performed the job. We could model this in schema.prisma
like so (thanks to @pantharshit00 on Slack for working up the schema):
model Car {
id Int @default(autoincrement()) @id
make String
model String
year Int
maintenance Maintenance[]
}
model Service {
id Int @default(autoincrement()) @id
name String
maintenance Maintenance[]
}
model Employee {
id Int @default(autoincrement()) @id
name String
maintenanceDone Maintenance[]
}
model Maintenance {
id Int @default(autoincrement()) @id
car Car @relation(fields: [carId], references: [id])
service Service @relation(fields: [serviceId], references: [id])
employee Employee @relation(fields: [employeeId], references: [id])
carId Int
serviceId Int
employeeId Int
performedAt DateTime @default(now())
}
Getting the Maintenance
records on a Car
is pretty easy:
prisma.car.findOne({ where: { id: 123 } }).maintenance()
But what if I wanted the Service
records associated with the car? Right now it would be something like:
prisma.car.findMany({
include: {
maintenance: {
select: {
service: true,
},
},
},
})
But what if you could simplify that syntax with the idea of the “has many through” relationship relationship: A Car
has many Service
records through Maintenance
records.
It would be amazing if you could get to those records using the same, simple syntax:
prisma.car.findOne({ where: { id: 123 } }).service()
Solution
Perhaps an extra parameter can be passed to @relation
somehow denoting that the records are reached through another? You give it the name of another field you’ve already defined on the model, like maintenance
:
model Car {
id Int @default(autoincrement()) @id
make String
model String
year Int
maintenance Maintenance[]
service Service[] @relation(through: maintenance)
}
Since we already have the definition of how a Service
relates to a Maintenance
in the Maintenance
model there’s no need to repeat the other relation arguments.
Additional context
Here’s some Rails documentation on has-many-through: https://guides.rubyonrails.org/association_basics.html#the-has-many-through-association
What do you think? Is it crazy enough to work?
Issue Analytics
- State:
- Created 3 years ago
- Reactions:85
- Comments:10
Just to keep thread alive… This would be an awesome feature to have. Also, really like the proposal approach.
we want has many through as well!