Working with One-to-Many Relations

1. Defining One-to-Many Relation

model User {
  id    Int    @id @default(autoincrement())
  posts Post[]
}
model Post {
  id       Int  @id @default(autoincrement())
  authorId Int
  author   User @relation(fields: [authorId], references: [id], onDelete: Cascade)
}
SideMarker
Parent (one)List field Post[]
Child (many)FK + @relation

2. Setting Foreign Key Field

TipDetail
IndexFK columns auto-indexed for joins
Composite FKUse array in fields/references

3. Configuring Back Reference

SideField
User.postsVirtual relation, no DB column
Post.authorVirtual; FK is authorId

4. Using Optional Foreign Keys

authorId Int?
author   User? @relation(fields: [authorId], references: [id], onDelete: SetNull)
EffectDetail
Detached postsPosts can exist without an author
Cascade choicePair optional FK with SetNull

5. Setting Relation Name

Use CaseExample
Author + reviewerTwo User relations on Post need names
Syntax@relation("AuthoredPosts", fields:[authorId], references:[id])

6. Configuring Referential Actions

ScenarioRecommendation
User deleted → postsCascade (remove posts)
Author optionalSetNull
Audit logRestrict (preserve history)
const user = await prisma.user.findUnique({
  where: { id: 1 },
  include: { posts: { where: { published: true }, take: 10, orderBy: { createdAt: "desc" } } }
});
OptionDetail
whereFilter included rows
take/skipLimit/offset included rows
orderBySort included rows
OperatorMeaning
someAt least one related row matches
everyAll related rows match
noneZero related rows match
is/isNotFor to-one relations
await prisma.user.findMany({
  where: { posts: { some: { published: true } } }
});
const users = await prisma.user.findMany({
  include: { _count: { select: { posts: true } } }
});
PatternDetail
_countUse inside include or select
Filtered countPass where: { posts: { where: { published: true } } }
await prisma.user.findMany({
  orderBy: { posts: { _count: "desc" } }
});
PatternUse
_countSort by number of related rows
Related fieldorderBy: { author: { name: "asc" } }