snchmt
snchmt
PPrisma
Created by snchmt on 4/15/2024 in #help-and-questions
How to cascade delete properly in a self-relation with mongodb ?
It is written in the doc that we need to set NoAction on self-relation database but how are we supposed to do it ? I tried getting all ids and using a deleteMany to delete parent and children together but I got a PrismaClientKnownRequestError.
generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}

model Tag {
id String @id @default(auto()) @map("_id") @db.ObjectId
name String
Parent Tag? @relation("Children", fields: [parentId], references: [id], onUpdate: NoAction, onDelete: NoAction)
parentId String? @db.ObjectId
Children Tag[] @relation("Children")
}
generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}

model Tag {
id String @id @default(auto()) @map("_id") @db.ObjectId
name String
Parent Tag? @relation("Children", fields: [parentId], references: [id], onUpdate: NoAction, onDelete: NoAction)
parentId String? @db.ObjectId
Children Tag[] @relation("Children")
}
async function getAllChildren(
prisma: PrismaClient,
tag?: Prisma.TagGetPayload<object>
): Promise<Prisma.TagGetPayload<object>[]> {
if (!tag) return [];
const childrenTags = await prisma.tag.findMany({
where: { parentId: tag.id },
});
const subTags = (
await Promise.all(childrenTags.map((tag) => getAllChildren(prisma, tag)))
).flat();

return [tag, ...subTags];
}

const allTags = await getAllChildren(
prisma,
await prisma.tag.findUnique({
where: { id: request.params.tagId },
})
);

const tagsIds = allTags.map((t) => t.id);
return prisma.tag.deleteMany({
where: {
id: { in: tagsIds },
},
});
async function getAllChildren(
prisma: PrismaClient,
tag?: Prisma.TagGetPayload<object>
): Promise<Prisma.TagGetPayload<object>[]> {
if (!tag) return [];
const childrenTags = await prisma.tag.findMany({
where: { parentId: tag.id },
});
const subTags = (
await Promise.all(childrenTags.map((tag) => getAllChildren(prisma, tag)))
).flat();

return [tag, ...subTags];
}

const allTags = await getAllChildren(
prisma,
await prisma.tag.findUnique({
where: { id: request.params.tagId },
})
);

const tagsIds = allTags.map((t) => t.id);
return prisma.tag.deleteMany({
where: {
id: { in: tagsIds },
},
});
23 replies