Search code examples
mysqlmany-to-manyrelational-databaserelationshipprisma

How to create and at the same time connect to a other model in a Implicit many-to-many relations?


I am new to Prisma. I have stuck on Prisma.brand.create method. Here is the model:

model Category {
  id String @id @default(cuid())
  slug String @unique
  name String @unique
  image String?
  createdAt DateTime @default(now())
  user   CMS_users @relation(fields: [userId], references: [id])
  userId String
  brands Brand[]
}

model Brand {
    id String @id @default(cuid())
    slug String @unique
    name String @unique
    image String?
    createdAt DateTime @default(now())
    user   CMS_users @relation(fields: [userId], references: [id])
    userId String
    categories Category[] 
}

This is generated schema in the MySQL:

CREATE TABLE `Brand` (
  `id` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  `slug` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  `name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  `image` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `createdAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  `userId` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `Brand_slug_key` (`slug`),
  UNIQUE KEY `Brand_name_key` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE `Category` (
  `id` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  `slug` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  `name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  `image` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `createdAt` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  `userId` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `Category_slug_key` (`slug`),
  UNIQUE KEY `Category_name_key` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE `_BrandToCategory` (
  `A` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  `B` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
  UNIQUE KEY `_BrandToCategory_AB_unique` (`A`,`B`),
  KEY `_BrandToCategory_B_index` (`B`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

The goal is here to create a Brand, at the same time connect one or more categories to that brand.

How Do I create it on Prisma client? right now it is like this:

 prisma.Brand.create({
      data: {
        name: name,
        slug: slug,
        userId: user,
        image: uploadedImage.secure_url,
        categories: {
          create: [
            { category: { connect: { id: "ckzpl0del0014vcv2ctift2f1" } } }
          ]
        }
      },
      include: {
        categories: true
      }
    })

The error shows:

PrismaClientValidationError: Invalid prisma.brand.create() invocation:

{
  data: {
    name: 'wassss',
    slug: 'wassss',
    userId: 'd5eea2a7-78d0-41d9-b090-171c9d7100cc',
    
    categories: {
    ~~~~~~~~~~
      create: [
        {
          category: {
            connect: {
              id: 'ckzpl0del0014vcv2ctift2f1'
            }
          }
        }
      ]
    }
  },
  include: {
    categories: true
  }
}

Unknown arg categories in data.categories for type BrandUncheckedCreateInput. Available args:

type BrandUncheckedCreateInput { id?: String slug: String name: String image?: String | Null createdAt?: DateTime userId: String }


Solution

  • In your case connectOrCreate API should solve your issue.

    const result = await prisma.brand.create({
        data: {
          name: "samsung",
          slug: "samsung",
          userId: "xxxx-xxxx-xxxx",
          categories: {
            connectOrCreate: {
              create: {
                name: 'phone',
              },
              where: {
                name: 'phone',
              }
            },
          },
        },
      });
    

    In this case connectOrCreate tries to find a category with name: 'phone', if found then it connects to it. If it can't find category then a new category named 'phone' will be created.