As in this document of Prisma, set
can be used to override the value of a relation.
const user = await prisma.user.update({
where: { email: '[email protected]' },
data: {
posts: {
set: [{ id: 32 }, { id: 42 }],
},
},
})
But when I tried it with explicit many-to-many relation, it does not work.
model Product {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
name String
description String?
price Decimal
sku String @unique
published Boolean @default(false)
tags ProductTag[]
}
model Tag {
id Int @id @default(autoincrement())
name String
products ProductTag[]
}
model ProductTag {
productId String
tagId Int
createdAt DateTime @default(now())
product Product @relation(fields: [productId], references: [id])
tag Tag @relation(fields: [tagId], references: [id])
@@id([productId, tagId])
}
My code to update Product
update(id: string, updateProductDto: UpdateProductDto) {
const tags = updateProductDto.tags.map((tag) => ({
productId_tagId: {
productId: id,
tagId: tag.id,
},
}));
console.log(JSON.stringify(tags));
return this.prisma.product.update({
where: { id: id },
data: {
...updateProductDto,
tags: {
set: [...tags],
},
},
});
}
I want to update the product's tag with the product's information.
How could I implement this correctly?
CodePudding user response:
I try a reply, but i would ask you to add the error messages, and your ProductTagWhereUniqueInput from node_modules/.prisma/client/index.d.ts
update(id: string, updateProductDto: UpdateProductDto) {
const tags = updateProductDto.tags.map((tag) => ({
// no need to encapsulate
productId: id,
tagId: tag.id,
}));
// prevent the tags property to be update in product table, because you want to use set.
delete updateProductDto.tags;
console.log(JSON.stringify(tags));
return this.prisma.product.update({
where: { id: id },
data: {
...updateProductDto,
tags: {
set: tags, // no need to rebuild the array
},
},
});
}
CodePudding user response:
You could delete existing productTag
records and then create new ones, in two separate queries. Then you could run the two queries as a transaction.
This is what it would look like
// do other updates to Tags with values from updateProductDto.
const deleteOldtags = prisma.productTag.deleteMany({
where: { productId: "__PRODUCT_ID__" },
});
const addNewTags = prisma.productTag.createMany({
data: [
{
productId: "__PRODUCT_ID__",
tagId: TAG_ID_VALUE
},
// ...array of productID and tagId objects.
]
})
let updateTags = await prisma.$transaction([deleteOldtags, addNewTags])
This is a workaround, that is slightly different from set
as it will create new records every time.