Relation
Relations are a fundamental concept in relational databases. They connect models into a graph and allow you to query interconnected data efficiently. In ZModel, relations are modeled using the @relation attribute. In most cases, it involves one side of the relation defining a foreign key field that references the primary key of the other side. By convention, we call the model that holds the foreign key the "owner" side.
One-to-one relation​
A typical one-to-one relation looks like this:
model User {
id Int @id
profile Profile?
}
model Profile {
id Int @id
user User @relation(fields: [userId], references: [id])
userId Int @unique
}
The Profile model holds the foreign key userId and is the owner of the relation. The pk-fk association is established by the @relation attribute, where the fields parameter specifies the foreign key field(s) and the references parameter specifies the primary key field(s) of the other side.
In one-to-one relations, the "non-owner" side must declare the relation field as optional (here User.profile), because there's no way to guarantee a User row always has a corresponding Profile row at the database level. The owner side can be either optional or required.
Relations can also be explicitly named, and it's useful to disambiguate relations when a model has multiple relations to the same model, or to control the constraint name generated by the migration engine.
model User {
id Int @id
profile Profile? @relation('UserProfile')
privateProfile Profile? @relation('UserPrivateProfile')
}
model Profile {
id Int @id
user User @relation('UserProfile', fields: [userId], references: [id])
userId Int @unique
userPrivate User @relation('UserPrivateProfile', fields: [userPrivateId], references: [id])
userPrivateId Int @unique
}
Please note that even though both sides of the relation now have the @relation attribute, only the owner side can have the fields and references parameters.
If a relation involves a model with composite PK fields, the FK fields must match the PK fields' count and types, and the fields and references parameters must be specified with those field tuples with matching order.
model User {
id1 Int
id2 Int
profile Profile?
@@id([id1, id2])
}
model Profile {
id Int @id
user User @relation(fields: [userId1, userId2], references: [id1, id2])
userId1 Int
userId2 Int
}