0

I have a query:

  createNotification: async (_, args, {req, res}) => {
    const followedBy = await prisma.user.updateMany({
      where: {
        following: {
          some: {
            id: req.userId
          },
        },
      },
      data: {
        notifications: {
          create: {
            message: args.message,
            watched: false,
          },
        },
      },
    })

And User and Notification models:

model User {
  id                Int     @id @default(autoincrement())
  email             String  @unique
  name              String
  user_name         String  @unique
  password          String
  movies            Movie[]
  notifications     Notification[]
  followedBy        User[]  @relation("UserFollows", references: [id])
  following         User[]  @relation("UserFollows", references: [id])
}

model Notification {
  id                Int     @id @default(autoincrement())
  link              String?
  movie_id          Int?
  message           String
  icon              String?
  thumbnail         String?
  user              User    @relation(fields: [userId], references: [id])
  userId            Int
  watched           Boolean
}

When I run my query I get an error:

Unknown arg `notifications` in data.notifications for type UserUpdateManyMutationInput. Did you mean `email`? Available args:
type UserUpdateManyMutationInput {
  email?: String | StringFieldUpdateOperationsInput
  name?: String | StringFieldUpdateOperationsInput
  user_name?: String | StringFieldUpdateOperationsInput
  password?: String | StringFieldUpdateOperationsInput
}

The strange thing is that this works:

    const followedBy = await prisma.user.findUnique({
      where: {id: req.userId},
      include: {
        followedBy: true,
      },
    });

    followedBy.followedBy.map(async(user) => {
      await prisma.user.update({
        where: {id: user.id},
        data: {
          notifications: {
            create: {
              message: args.message,
              watched: false,
            },
          },
        },
      });
    });

But this isn't making the best of what Prisma offers.

Peter Boomsma
  • 8,851
  • 16
  • 93
  • 185

1 Answers1

0

As of September 2021, Prisma does not support mutating nested relations in a top-level updateMany query. This is what the typescript error is trying to tell you, that you can only access email, name, user_name and password fields inside data. There's an open feature request for this which you could follow if you're interested.

For the schema that you have provided, here's a possible workaround that's slightly less readable but more optimized than your current solution.

createNotification: async (_, args, {req, res}) => {
    // get the followers array of req.userId
    const followedBy = await prisma.user.findUnique({
        where: { id: req.userId },
        include: {
            followedBy: true,
        },
    });

    // array of notification objects to be created, one for each follower of req.userId
    let messageDataArray = followedBy.followedBy.map((user) => {
        return {
            userId: user.id,
            message: args.message,
            watched: false,
        };
    });

    // do a bulk createMany.
    // Since it's one query, it should be more optimized than running an update for each user in a loop.
    await prisma.notification.createMany({
        data: messageDataArray,
    });
};

If you're interested, here's the docs reference for the kinds of nested updates that are possible.

Tasin Ishmam
  • 5,670
  • 1
  • 23
  • 28