Следующий JS с помощью Prisma — Обновление ролей пользователей на основе

#reactjs #rest #next.js #prisma

Вопрос:

Я довольно новичок в обоих Next.js и Призма. Я работаю над приложением для управления городскими советами, и поэтому администратор этого приложения может создавать пользователей и роли и назначать роли пользователям (это будут сотрудники городского совета).

Каждый пользователь может получать несколько ролей, и эти роли могут быть обновлены, то есть администратор может удалить или назначить пользователю больше ролей, когда захочет.

В моей схеме базы данных у меня есть таблица Customer (она же пользователь, потому что пользователь-зарезервированное имя в postgresql), таблица Role и таблица Customer_role , которая представляет отношение n:m между пользователем и его ролями.

Каков лучший способ обновления ролей пользователей с помощью prisma? Прямо сейчас именно так я это и делаю:

 const updateUser = async (req: NextApiRequest, res: NextApiResponse) => {
  const {
    query: { id },
    body: { name, email, roles },
  } = req as { query: { [key: string]: string }; body: any };

  try {
    await prisma.customer.update({
      where: { id },
      data: { name, email },
    });
    await updateUserRoles(id, roles);
    const response = await prisma.customer.findUnique({
      where: { id: id },
      include: {
        customer_roles: {
          select: {
            role: {
              select: {
                id: true,
                name: true,
              },
            },
          },
        },
      },
    });
    res.status(200).json(response);
  } catch (error) {
    res.status(400).json((error as Error).message);
  }
};

const updateUserRoles = async (userID: string, roles: { id: string }[]) => {
  try {
    await prisma.customer_role.deleteMany({
      where: {
        customer_id: userID,
      },
    });
    roles.map(async (role: { id: string }) => {
      await prisma.customer_role.create({
        data: {
          customer_id: userID,
          role_id: role.id,
        },
      });
    });
  } catch (error) {
    throw new Error(error);
  }
}; 

Первоначально я получаю массив ролей, которые я хочу назначить пользователю, но затем, когда я хочу обновить их, я удаляю все текущие роли пользователей и назначаю их снова. Это создает ошибку , потому что объект ответа, который должен вернуть обновленного пользователя с его новыми ролями, не ожидает функцию updateUserRoles и возвращает роли пользователей в виде пустого массива. Только когда я обновлю страницу и снова получу пользователей, эта ошибка будет исправлена. Вот моя схема призмы, а также.

 model role {
  id                  String          @id @default(uuid())
  @db.Uuid
  name                String          @db.VarChar(255)
  polls               permission
  news                permission
  events              permission
  work_orders         permission
  pharmacies          permission
  points_of_interest  permission
  subscription_events permission
  customer_roles      customer_role[]
  created_at          DateTime        @default(now()) @db.Timestamptz(6)
  updated_at          DateTime?       @default(now()) @db.Timestamptz(6)

  @@index([name], name: "idx_role_name")
}

model customer_role {
  id          String   @id @default(uuid()) @db.Uuid
  customer_id String   @db.Uuid
  role_id     String   @unique @db.Uuid
  customer    customer @relation(fields: [customer_id], references: [id], onDelete: Cascade)
  role        role     @relation(fields: [role_id], references: [id])
}

model customer {
  id              String           @id @default(uuid()) @db.Uuid
  name            String           @db.VarChar(255)
  email           String           @unique @db.VarChar(255)
  external_uuid   String?          @unique @db.Uuid
  password        String?          @db.VarChar(255)
  created_at      DateTime         @default(now()) @db.Timestamptz(6)
  updated_at      DateTime?        @default(now()) @db.Timestamptz(6)
  work_order_user work_order_user?
  customer_roles  customer_role[]

  @@index([name], name: "idx_customer_name")
  @@index([external_uuid], name: "idx_customer_external_uuid")
} 

Ответ №1:

Причина, по которой вы не видите обновленные роли, заключается в том, что вы используете async внутри функции map под updateUserRoles функцией. Это будет выполняться асинхронно, и вы не получите требуемый ответ, так как это будет выполняться в фоновом режиме.

Лучшим способом сделать это было бы использовать upsert:

 const updateUserRoles = async (userID: string, roles: { id: string }[]) => {
  try {
    await prisma.$transaction(
    roles.map((role) =>
      prisma.customer_role.upsert({
        where: { id: role.id },
        create: { customer_id: userId, role_id: role.id },
        update: {},
      })
    )
  )
  } catch (error) {
    throw new Error(error);
  }
}