I'm struggling to find documentation for handling explicit many to many relationships in Prisma. So I have resorted to dev by Stackoverflow....
I have a many to many relationship:
model Fight {
id Int @id @default(autoincrement())
name String
fighters FighterFights[]
}
model Fighter {
id Int @id @default(autoincrement())
name String @unique
fights FighterFights[]
}
model FighterFights {
fighter Fighter @relation(fields: [fighterId], references: [id])
fighterId Int
fight Fight @relation(fields: [fightId], references: [id])
fightId Int
@@id([fighterId, fightId])
}
I am trying to delete a fight and delete the relationship in FighterFights but not delete the actual fighter.
I tried the following:
const result = await prisma.fight.delete({
where: {
id: Number(id),
},
})
but get the error:
PrismaClientKnownRequestError:
Invalid `prisma.fight.delete()` invocation:
Foreign key constraint failed on the field: `FighterFights_fightId_fkey (index)`
I then also tried:
const result = await prisma.fight.delete({
where: { id: Number(id) },
data: {
fighterFights: {
deleteMany: {
where: { fightId: id },
},
},
},
})
But I get the error:
PrismaClientValidationError:
Invalid `prisma.fight.delete()` invocation:
{
where: {
id: 1
},
data: {
~~~~
fighterFights: {
deleteMany: {
where: {
fightId: '1'
}
}
}
}
}
Unknown arg `data` in data for type Fight. Available args:
type deleteOneFight {
where: FightWhereUniqueInput
}
I also tried:
const result = await prisma.fight.delete({
where: {
id: Number(id),
},
data: {
fighterFights: {
deleteMany: [{ fightId: { equals: Number(id) } }],
},
},
})
but get the error:
Invalid `prisma.fight.delete()` invocation:
{
where: {
id: 1
},
data: {
~~~~
fighterFights: {
deleteMany: [
{
fightId: {
equals: 1
}
}
]
}
}
}
Unknown arg `data` in data for type Fight. Available args:
type deleteOneFight {
where: FightWhereUniqueInput
}
here you go a way to do that:
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
const saveData = async () => {
const fighter1 = await prisma.fighter.create({
data: {
name: 'Ryu',
},
})
const fighter2 = await prisma.fighter.create({
data: {
name: 'Ken',
},
})
console.log('FIGHTERS');
console.log(JSON.stringify(fighter1, null, 2));
console.log(JSON.stringify(fighter2, null, 2));
const fight = await prisma.fight.create({
data: {
name: 'Ryu vs Ken',
fighters: {
createMany: {
data: [
{
fighterId: fighter1.id,
},
{
fighterId: fighter2.id,
},
]
},
},
},
select: {
id: true,
fighters: {
select: {
fighter: true,
},
},
},
});
console.log('FIGHTS');
console.log(JSON.stringify(await prisma.fight.findMany({ include: { fighters: true } }), null, 2));
const fighterFightsToDelete = prisma.fighterFights.deleteMany({
where: {
fightId: fight.id,
}
})
const fightToDelete = prisma.fight.delete({
where: {
id: fight.id,
}
})
await prisma.$transaction([ fighterFightsToDelete, fightToDelete ])
console.log('RESULT');
console.log(JSON.stringify(await prisma.fight.findMany({ include: { fighters: true } }), null, 2));
console.log(JSON.stringify(await prisma.fighter.findMany({ include: { fights: true } }), null, 2));
}
saveData()
And the result is the following :)