在 Prisma 中更新多对多关系

Updating many-to-many relations in Prisma

我有一组关于皮肤问题的复选框。用户可以在提交前check/uncheck他们,这意味着每次提交的皮肤问题集都可以不同。

我在 Prisma 模式中将其建模为 'explicit' 多对多关系。

model User {
  id                 String                 @id @default(cuid())
  name               String?
  nickname           String?                @unique
  ...
  skinConcerns       SkinConcernsForUsers[]
  ...
}

model SkinConcern {
  id   Int                    @id @default(autoincrement())
  name String                 @unique
  user SkinConcernsForUsers[]
}

model SkinConcernsForUsers {
  user          User        @relation(fields: [userId], references: [id])
  userId        String
  skinConcern   SkinConcern @relation(fields: [skinConcernId], references: [id])
  skinConcernId Int

  @@id([userId, skinConcernId])
}

然后,SkinConcerns table 使用以下值播种,使用 prisma.skinConcern.createMany:

"ACNE",
"DRYNESS",
"OILY_SKIN",
"PIGMENTATION",
"REDNESS",
"WRINKLES",

SkinConcerns 在 Update 突变输入中以字符串数组的形式出现,例如["PIGMENTATION", "REDNESS"].

我想从 prisma.user.update 查询更新用户 (SkinConcernsForUsers) 的皮肤问题,但这很棘手,因为我不仅要创建 SkinConcerns,而且必须连接到现有集皮肤问题。

我在user中直接set试过skinConcerns,喜欢

await prisma.user.update({
  where: { nickname },
  data: {
    // ... other user data
    skinConcerns: {
      set: [
        {
          skinConcern: {
            connect: { name: "PIGMENTATION" },
          },
        },
        {
          skinConcern: {
            connect: { name: "REDNESS" },
          },
        },
      ],
    },
    // ... other user data
  }
});

还有很多其他事情,但这当然不是一个正确的论点并且因错误而失败

Unknown arg `connect` in data.skinConcerns.update.0.where.connect for type SkinConcernsForUsersWhereUniqueInput. Did you mean `select`?
Argument data for data.skinConcerns.update.0.data is missing.
Unknown arg `connect` in data.skinConcerns.update.1.where.connect for type SkinConcernsForUsersWhereUniqueInput. Did you mean `select`?
Argument data for data.skinConcerns.update.1.data is missing.

有办法吗?甚至可以在 prisma.user.update 中更新吗?

我想我可以直接更新 SkinConcernsForUsers。在这种情况下,我是否应该只删除与用户关联但不在用户输入 ["PIGMENTATION", "REDNESS"] 中的所有行,然后创建尚不存在的行?在棱镜代码中它会是什么样子?

首先,我会更改 SkinConcern 的架构。 id 字段不是必需的,它会使查询变得复杂(在尝试 connect/disconnect 记录时,您不需要将每个 name 映射到 id

name 字段作为主键就足够了,因为它对于特定记录始终是唯一的。

更改后的架构如下所示

model SkinConcern {
  name String                  @id    // name is the new @id. 
  user SkinConcernsForUsers[]
}

model SkinConcernsForUsers {
  user          User        @relation(fields: [userId], references: [id])
  userId        String
  skinConcern   SkinConcern @relation(fields: [skinConcernName], references: [name])
  skinConcernName String

  @@id([userId, skinConcernName])
}

您想要执行的查询可以使用 SkinConcernsForUsers 模型分两步执行。

  1. 步骤 1: 删除用户连接的现有 SkinConcernsForUsers 记录。这些不再相关,因为您想覆盖之前的选择。

  2. 步骤 2: 使用新选择创建新的 SkinConcernsForUsers 记录。

这是代码的样子


// step 1
await prisma.skinConcernsForUsers.deleteMany({
    where: {
        userId: "1",
    },
});

// step 2
await prisma.skinConcernsForUsers.createMany({
    data: [
        {
            userId: "1",
            skinConcernName: "REDNESS",
        },
        {
            userId: "1",
            skinConcernName: "PIGMENTATION",
        },
    ],
});