typescriptgraphqlprismaprisma-graphqlprisma2

Prisma many-to-many relations: create and connect


In my Prisma schema, I have a many-to-many relationship between posts and categories. I've added @map options to match the Postgres snake_case naming convention:

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")
}

I'm trying to create a post with multiple categories at the same time. If a category exists, I'd like to connect the category to the post. If the category doesn't exist, I'd like to create it. The creation part is working well, but the connection part is problematic:

  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
        },
      },
    },
  });

How can I connect an existing category to a new post with the schema that I have?


Solution

  • What you need here is connectOrCreate.

    So something like this should work:

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

    You can also read more about this in the docs here