我同意,如果 Prisma 能够更原生地支持这种关系应该是对称的自我关系(例如,当且仅当 userB 是 userA 的朋友时,userA 是 userB 的朋友),那就太好了。
然而,据我所知,Prisma 坚持认为这种关系有两个“方面”。 (如果有人更了解,我很想听听!)因此,接下来是我正在采取的方法,它避免了必须查询这两个关系才能找到用户的完整朋友集。
Concept
-
我们将使用关系的一个“侧面”来包含完整的朋友集。另一“面”的存在只是为了满足 Prisma 的要求,我们永远不会直接查询它。
-
添加或删除好友关系时,我们将进行两次 prisma 调用,一次更新每个对象。
Code
架构文件:
model User {
id Int @id @default(autoincrement())
name String?
friends User[] @relation("UserFriends")
// This second "side" of the UserFriends relation exists solely
// to satisfy prisma's requirements; we won't access it directly.
symmetricFriends User[] @relation("UserFriends")
}
添加和删除好友的方法(这里有很多多余的代码可以抽象出来,但我认为这样读起来更清楚):
const addFriendship = async (userIdA: string, userIdB: string) => {
await prisma.user.update({
where: {id: userIdA},
data: {friends: {connect: [{id: userIdB}]}},
});
await prisma.user.update({
where: {id: userIdB},
data: {friends: {connect: [{id: userIdA}]}},
});
};
const removeFriendship = async (userIdA: string, userIdB: string) => {
await prisma.user.update({
where: {id: userIdA},
data: {friends: {disconnect: [{id: userIdB}]}},
});
await prisma.user.update({
where: {id: userIdB},
data: {friends: {disconnect: [{id: userIdA}]}},
});
}
通过这种方法,人们可以加载用户并以预期的方式获取他们的所有朋友,例如
const getUserWithFriends = async (userId) =>
await prisma.user.find({
where: {id: userId},
include: {friends: true},
});