【问题标题】:Prisma many-to-many relations: create and connectPrisma 多对多关系:创建和连接
【发布时间】:2021-05-03 03:11:24
【问题描述】:

在我的 Prisma 架构中,帖子和类别之间存在多对多关系。我添加了 @map 选项以匹配 Postgres snake_case 命名约定:

model Post {
  id         Int            @id @default(autoincrement())
  title      String
  body       String?
  categories PostCategory[]

  @@map("post")
}

model Category {
  id    Int            @id @default(autoincrement())
  name  String
  posts PostCategory[]

  @@map("category")
}

model PostCategory {
  categoryId Int      @map("category_id")
  postId     Int      @map("post_id")
  category   Category @relation(fields: [categoryId], references: [id])
  post       Post     @relation(fields: [postId], references: [id])

  @@id([categoryId, postId])
  @@map("post_category")
}

我正在尝试同时创建一个包含多个类别的帖子。如果存在某个类别,我想connect 该类别的帖子。如果该类别不存在,我想创建它。创建部分运行良好,但连接部分有问题:

  await prisma.post.create({
    data: {
      title: 'Hello',
      categories: {
        create: [{ category: { create: { name: 'News' } } }],
        connect: {
          categoryId_postId: { categoryId: 1, postId: ? }, // This doesn't work, even if I had the postId
        },
      },
    },
  });

如何使用我拥有的架构将现有类别连接到新帖子?

【问题讨论】:

    标签: typescript graphql prisma prisma-graphql prisma2


    【解决方案1】:

    你需要的是connectOrCreate

    所以这样的事情应该可以工作:

          await prisma.post.create({
            data: {
              title: 'Hello',
              categories: {
                create: [
                  {
                    category: {
                      create: {
                        name: 'category-1',
                      },
                    },
                  },
                  { category: { connect: { id: 10 } } },
                ],
              },
            },
          });
    

    您还可以在文档here 中阅读更多相关信息

    【讨论】:

    • 这表现出奇怪的行为。如果{ categoryId: 1, postId: 1 } 网桥记录存在于post_category 表中,则它将网桥记录替换为{ categoryId: 1, postId: new_id }。换句话说,它将另一个帖子的类别重新分配给这个新帖子。创建新帖子时,我不希望任何其他帖子受到影响。如果类别不存在,我想创建一个新类别,如果存在,我想添加一个新的桥接记录。这里有一个使用 createset 隐式关系的好例子:(后面的网址),但它不起作用 b/c 我正在使用显式关系。
    • 这是我在之前评论中提到的 URL:prisma.io/docs/support/help-articles/… 那里的示例使用 tags: { set: [{ id: 1 }, { id: 2 }], create: { name: 'typescript' } },这是我想做的,但似乎无法得到它处理我的明确关系。
    • 根据您链接到的文档,我想我想要这样的东西,但这会引发异常,因为我无法从 categoryId_postId 链接到 category(对格式感到抱歉): connectOrCreate: { create: { category: { create: { name: 'category-1' } }, }, where: { categoryId_postId: { category: { name: 'category-1' }, }, }
    • 在这种情况下,这应该可以工作:await prisma.post.create({ data: { title: 'title', categories: { create: { category: { connect: { id: 1 } } } }, }, }) 这应该将帖子连接到现有类别,并将在连接表中创建关系。
    【解决方案2】:

    这个问题把我逼疯了,所以我会在这里贡献我的解决方案,以防它帮助别人。首先,请阅读:https://www.prisma.io/docs/concepts/components/prisma-schema/relations/many-to-many-relations

    我的架构与所讨论的架构相似,唯一的区别是我有文件而不是帖子和标签而不是类别。要将创建的文件的标签链接到现有标签,我使用了这个:

      await Promise.all(DEFAULT_FILES[2].map(file => prisma.file.create({
        data: {
          ...file,
          user_id: userId,
          parent_id: homeFolder.id,
          tags: {
            create: file.tags?.map(name => ({
              tag: {
                connect: {
                  id: tags.find(t => t.name === name)?.id
                }
              }
            }))
          },
        }
      })))
    

    【讨论】:

      【解决方案3】:
      await prisma.postCategory.create({
        data: {
          category: {
            connectOrCreate: {
              id: categoryId
            }
          },
          posts: {
            create: [
              {
                title: 'g3xxxxxxx',
                body: 'body g3xxxxx'
              }
            ],
          },
        },
      })
      

      您应该连接到现有记录,然后创建要与第一个记录相关的记录。

      https://www.prisma.io/docs/concepts/components/prisma-client/relation-queries(连接现有记录)

      【讨论】:

        【解决方案4】:

        显式多对多创建/更新现有标签read more here

        let args =[1,2,3,4]
        tags: {
              create: args.tags?.map(tagId=>({
                  tag:{
                      connect:{
                          id:tagId
                      }
                  }
              }))
            },
         }

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-07-25
          • 2022-01-27
          • 1970-01-01
          • 1970-01-01
          • 2021-10-03
          • 2021-07-23
          • 2022-01-19
          • 2017-06-23
          相关资源
          最近更新 更多