many-to-manyprismaprisma2

Using explicit Many to Many Relation in Prisma


I have the following User and Group models that share a many-to-many relation:

    model User {
      id    String     @id @default(uuid())
      email String  @unique

      groups UsersGroups[]
    
      @@map("user")
    }
    
    model Group {
      id String @id @default(uuid())
      name String

      users UsersGroups[]
    
      @@map("group")
    }
    
    model UsersGroups {
      user     User    @relation(fields: [userId], references: [id])
      userId   String  @map(name: "user_id")
      group      Group     @relation(fields: [groupId], references: [id])
      groupId    String  @map(name: "group_id")
    
      @@id([userId, groupId])
      @@map("users_groups")
    }

I'm having trouble using the connect API in Prisma to connect the users and groups. Here's what I have:

    await prisma.group.update({
        where: {
          id: groupId,
        },
        data: {
          users: {
            connect: users.map((user) => ({ id: user.id })),
          },
        },
        include: { users: true },
      });

That doesn't work and here is the error I'm getting in the console:


    PrismaClientValidationError: 
        Invalid `prisma.group.update()` invocation:
        
        {
          where: {
            id: '64ce24c7-3054-42f2-b49f-4cdb52cf1bc7'
          },
          data: {
            users: {
              connect: [
                {
                  id: '0b3f4a51-0efe-4b0a-8763-e71bc8091b86'
                  ~~
                }
              ]
            }
          },
          include: {
            users: true
          }
        }
        
        Unknown arg `id` in data.users.connect.0.id for type UsersGroupsWhereUniqueInput. Available args:
        
        type UsersGroupsWhereUniqueInput {
          userId_groupId?: UsersGroupsUserIdGroupIdCompoundUniqueInput
        }

From that above, it looks as though it's attempting to connect a user with id: '0b3f4a51-0efe-4b0a-8763-e71bc8091b86' (which is a user that exists) to the group with id: '64ce24c7-3054-42f2-b49f-4cdb52cf1bc7' (which also exists).

I'd be very grateful if someone could point out where I'm going wrong as I've been going in circles with this for a while now...


Solution

  • You are using an explicit many-to-many relation, cf. https://www.prisma.io/docs/concepts/components/prisma-schema/relations/many-to-many-relations#explicit-many-to-many-relations

    I.e. you have defined the model UsersGroups yourself. As a consequence, you would have to manage/create the records in this table yourself and connect it with the entry in the third table, e.g. like this (haven't tested it):

    prisma.group.update({
      where: {
        id: groupId,
      },
      data: {
        users: { create: { user: { connect: { id: userId } } } },
      },
      include: { users: true },
    });
    

    or if you want to loop over an list:

    prisma.group.update({
      where: {
        id: groupId,
      },
      data: {
          users: {
            create: users.map((user) => ({
              user: { connect: { id: user.id } },
            })),
          },
        },
      include: { users: true },
    });
    

    I would suggest to replace groups UsersGroups[] and users UserGroups[] with userGroups UsersGroups[] in the schema to make it clearer.

    As an alternative to explicit relationships you could try to use implicit many-to-many relations in the schema like this:

        model User {
          id    String     @id @default(uuid())
          email String  @unique
    
          groups Group[]
        
          @@map("user")
        }
        
        model Group {
          id String @id @default(uuid())
          name String
    
          users User[]
        
          @@map("group")
        }
    

    cf. https://www.prisma.io/docs/concepts/components/prisma-schema/relations/many-to-many-relations#implicit-many-to-many-relations