For context, my schema resembles something like this:
model Plant {
id Int @id @default(autoincrement())
// Omitted data here...
climateRegions PlantClimateRegion[]
attractedWildlife PlantWildlife[]
}
model PlantClimateRegion {
plant Plant @relation(fields: [plantId], references: [id], onDelete: Cascade)
plantId Int
region ClimateRegion
@@id(name: "plantClimateId", [plantId, region])
}
model PlantWildlife {
plant Plant @relation(fields: [plantId], references: [id], onDelete: Cascade)
plantId Int
wildlife AttractedWildlife
@@id(name: "plantWildlifeId", [plantId, wildlife])
}
ClimateRegion and AttractedWildlife are string ENUMS.
my update function does as follows:
await prisma.$transaction(async (tx) => {
await tx.plantClimateRegion.deleteMany({
where: {
plantId: id,
},
});
await tx.plantWildlife.deleteMany({
where: {
plantId: id,
},
});
const climateRegionRecords = climateRegions.map(
(region: ClimateRegion) => ({
region,
})
);
const wildlifeRecords = attractedWildlife.map(
(wildlife: AttractedWildlife) => ({
wildlife,
})
);
updatedPlant = await tx.plant.update({
where: {
id,
},
data: {
// Omitted data here...
climateRegions: {
createMany: { data: climateRegionRecords },
},
attractedWildlife: {
createMany: { data: wildlifeRecords },
},
},
});
I know that I could conditionally delete instead of deleting all, but I’m wondering if Prisma offers some sort of onUpdate referential action or other options that would prevent from explicitly deleting and adding?
// Workaround solution
I’ve tried the upsert action but unsure if it’s possible in my use case, or how to use it properly.
As a temporary solution, I chose to manually delete all rows in the composite tables by Id, and re-add them. This works but this solution will likely cause performance issues as things scale due to inefficiency.