typescript Prisma更新插入和删除旧关系

camsedfj  于 2022-11-26  发布在  TypeScript
关注(0)|答案(1)|浏览(147)

我有一个在Posts上撰写的项目,每个帖子都可以有一个Tags的集合。我正在尝试启用一个编辑功能,允许更新/添加/删除帖子标签。目前,我的查询将更新这些标签,但我遇到了一些由删除方面引起的麻烦。任何时候新标签被创建,因为它们当时没有ID,它们会立即被删除。

await Prisma.post.update({
            where: {
                id: postId,
            },
            data: {
                title,
                content,
                updatedAt: new Date(),
                tags: {
                    // Upsert tags, remove tags that are not in the request
                    upsert: tags.map((tag) => ({
                        where: {
                            id: tag.id ? tag.id : "0",
                        },
                        create: {
                            name: tag.name,
                            color: tag.color,
                            creator: {
                                connect: {
                                    id: session.user.id,
                                },
                            },
                        },
                        update: {
                            name: tag.name,
                            color: tag.color,
                        },
                    })),
                    deleteMany: {
                        id: {
                            notIn: tags.map((tag) => tag.id ?? "0"),
                        },
                    },
                },
            },
            include: {
                tags: true,
            },
        });

我尝试过各种解决方案,比如键入名称或其他属性(如名称和颜色),但似乎没有一种解决方案能解决这个问题,因为它们最终会复制标签并导致类似的错误。
下面是我正在使用的Post和Tag模型的模式。
Post

model Post {
    id        String    @id @default(uuid())
    createdAt DateTime  @default(now())
    updatedAt DateTime  @updatedAt
    deletedAt DateTime?

    title    String
    content  String
    authorId String
    author   User      @relation(fields: [authorId], references: [id])
    comments Comment[]
    tags     Tag[]
}

Tag

model Tag {
    id        String   @id @default(uuid())
    createdAt DateTime @default(now())
    updatedAt DateTime @updatedAt

    name      String
    color     String
    creatorId String
    creator   User   @relation(fields: [creatorId], references: [id])
    posts     Post[]
}

如果有人能给我指出如何处理这种情况的正确方向,我将不胜感激。

jq6vz3qz

jq6vz3qz1#

在插入新标签之前,您应该删除事务中的步骤,删除查询中没有的标签。

具有交互式事务

在您的schema.prisma中,您应该启用interactiveTransactions,以便:

generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["interactiveTransactions"]
}

然后在交易中减少步骤

// Remove <Post> if you aren't in typescript
await prisma.$transaction<Post>(async (trx) => {
  const existingTags = tags.filter(({ id }) => id);
  const newTags = tags.filter(({ id }) => !id);

  await trx.tag.deleteMany({
    where: {
      id: {
        notIn: existingTags.map(({ id }) => id),
      },
    },
  });
  // Update the existing tags
  await Promise.all(
    tags.map((tag) =>
      trx.tag.update({
        where: {
          id: tag.id,
        },
        data: {
          color: tag.color,
          name: tag.name,
        },
      })
    )
  );
  await trx.tag.createMany({
    data: newTags.map((tag) => ({
      ...tag,
      creator: {
        connect: {
          id: session.user.id,
        },
      },
    })),
  });
  return trx.post.update({
    where: {
      id: postId,
    },
    data: {
      title,
      content,
      updatedAt: new Date(),
    },
    include: {
      tags: true,
    },
  });
});

相关问题