#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);
}
}