You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Prisma中为Post查询结果添加isLiked字段及类型存储咨询

问题描述

我存在User与Post的隐式多对多关系:用户可点赞多篇帖子,帖子可被多个用户点赞。对应的Prisma Schema如下:

model User {
  id         String    @id @default(dbgenerated("uuid_generate_v4()")) @db.Uuid
  posts      Post[]    @relation("author")
  likes      Post[]    @relation("like")

  @@map("users")
}

model Post {
  id         String    @id @default(dbgenerated("uuid_generate_v4()")) @db.Uuid
  author     User      @relation("author", fields: [author_id], references: [id])
  author_id  String    @db.Uuid
  comments   Comment[]
  likedBy    User[]    @relation("like")

  @@map("posts")
}

现在需要查询帖子列表用于渲染,每个帖子需显示当前用户是否已点赞的状态,如何通过一次查询得到Post & { isLiked: boolean }结构?此外,由于该类型并非来自Prisma,遵循单一数据源原则,应将其存储在何处?

解决方案

一、一次查询获取带点赞状态的帖子列表

可以利用Prisma的查询API结合SQL的exists逻辑,在单次查询中直接计算出每个帖子的isLiked状态,有两种实现方式:

方式1:使用Prisma的$expr语法

const currentUserId = "当前用户的UUID"; // 替换为实际当前用户ID

const posts = await prisma.post.findMany({
  select: {
    id: true,
    author_id: true,
    author: { select: { id: true /* 按需添加作者字段 */ } },
    // 其他需要的Post字段
    isLiked: {
      $expr: {
        $exists: prisma.user.findFirst({
          where: {
            id: currentUserId,
            likes: { some: { id: { $eq: prisma.post.id } } }
          }
        })
      }
    }
  }
});

方式2:使用原生SQL片段(性能更优)

隐式多对多关系会自动生成中间表(默认命名为users_likes_posts,可通过Prisma配置自定义),直接通过SQL判断当前用户是否在帖子的点赞列表中:

const currentUserId = "当前用户的UUID";

const posts = await prisma.post.findMany({
  select: {
    id: true,
    author_id: true,
    author: true,
    // 其他需要的Post字段
    isLiked: {
      sql: `EXISTS (SELECT 1 FROM users_likes_posts WHERE "userId" = '${currentUserId}' AND "postId" = "Post"."id")`
    }
  }
});

两种方式返回的结果都会包含Post的所有选中字段以及isLiked布尔值,完全符合Post & { isLiked: boolean }的结构要求。

二、自定义类型的存储位置

遵循单一数据源原则,建议将这个自定义类型:

  • 放在Prisma Schema所在目录的类型声明文件中,比如prisma/post-types.ts,和Prisma自动生成的类型(@prisma/client导出)保持相近,便于统一维护。
  • 类型声明示例:
import { Post } from "@prisma/client";

export type PostWithLikeStatus = Post & {
  isLiked: boolean;
};

后续业务代码中直接导入该类型即可,避免重复定义,确保类型的单一性。

内容的提问来源于stack exchange,提问作者Arc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 01:44:54