Search code examples
typescriptpostgresqlmany-to-manyprisma

How to create a new many to many relationship with existing records?


I have a many to many relationship modelling a boxing match:

  • A fight can have multiple fighters (always 2)
  • A fighter can be in multiple fights

My schema looks like this:

model Fight {
  id            Int     @id @default(autoincrement())
  fighters      FighterFights[]
}

model Fighter {
  id        Int     @id @default(autoincrement())
  name      String  @unique
  fights    FighterFights[]
}

model FighterFights {
  fighter      Fighter     @relation(fields: [fighterId], references: [id])
  fighterId    Int
  fight        Fight @relation(fields: [fightId], references: [id])
  fightId      Int

  @@id([fighterId, fightId])
}

I want to create a new fight with 2 existing fighters. This is what I've tried:

const result = await prisma.fight.create({
  data: {
    fighters: {
      connect: [{ id: fighter1 }, { id: fighter2 }],
    },
  },
})

But I get this typescript error:

Type '{ id: any; }' is not assignable to type 'FighterFightsWhereUniqueInput'.
  Object literal may only specify known properties, and 'id' does not exist in type 'FighterFightsWhereUniqueInput'.

How should my prisma.fight.create function invocation look?


Solution

  • You can do that as follow:

    const { PrismaClient } = require('@prisma/client')
    const prisma = new PrismaClient()
    
    const saveData = async () => {
      const fighter1 = await prisma.fighter.create({
        data: {
          name: 'Ryu',
        },
      })
      const fighter2 = await prisma.fighter.create({
        data: {
          name: 'Ken',
        },
      })
    
      console.log(JSON.stringify(fighter1, null, 2));
      console.log(JSON.stringify(fighter2, null, 2));
    
      const fight = await prisma.fight.create({
        data: {
          fighters: {
            createMany: {
              data: [
                {
                  fighterId: fighter1.id,
                },
                {
                  fighterId: fighter2.id,
                },
              ]
            },
          },
        },
        select: {
          id: true,
          fighters: {
            select: {
              fighter: true,
            },
          },
        },
      });
    
      console.log(JSON.stringify(fight, null, 2));
    }
    
    saveData()
    

    It will return the following

    enter image description here