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

Laravel查询需求:获取带创建者信息及当前用户点赞标记的帖子列表

Laravel 查询修正方案:避免帖子重复并正确返回点赞标记

问题根源

直接关联 post_likes 表会导致重复数据——同一帖子被多个用户点赞时,每条点赞记录都会生成一条重复的帖子数据。解决核心是不通过关联查询拉取所有点赞记录,而是通过子查询/条件统计判断当前用户是否点赞。


方案1:Eloquent 条件统计(推荐)

利用 withCount 统计当前用户对单帖的点赞数,再转成布尔标记,同时加载帖子创建者信息:

$currentUserId = auth()->id();

$posts = Post::with('user:id,username,profile_pic,email') // 仅加载需要的用户字段,优化性能
    ->withCount([
        'postLikes as liked' => function ($query) use ($currentUserId) {
            $query->where('user_id', $currentUserId);
        }
    ])
    ->get()
    ->map(function ($post) {
        // 把统计数转成布尔标记:大于0则已点赞
        $post->liked = $post->liked > 0;
        return $post;
    });

方案2:子查询判断存在性

通过 selectSub 编写子查询,直接判断当前用户是否给该帖子点赞:

$currentUserId = auth()->id();

$posts = Post::select('posts.*')
    ->selectSub(function ($query) use ($currentUserId) {
        $query->selectRaw('1')
            ->from('post_likes')
            ->whereColumn('post_likes.post_id', 'posts.id')
            ->where('post_likes.user_id', $currentUserId);
    }, 'liked')
    ->with('user:id,username,profile_pic,email')
    ->get()
    ->map(function ($post) {
        // 子查询无结果时返回null,转成false
        $post->liked = !is_null($post->liked);
        return $post;
    });

方案3:原生SQL查询

如果偏好原生查询,用 EXISTS 子句判断点赞状态:

$currentUserId = auth()->id();

$posts = DB::table('posts')
    ->select([
        'posts.*',
        'users.username',
        'users.profile_pic',
        'users.email',
        DB::raw('CASE WHEN EXISTS (SELECT 1 FROM post_likes WHERE post_likes.post_id = posts.id AND post_likes.user_id = ?) THEN 1 ELSE 0 END AS liked')
    ])
    ->join('users', 'posts.user_id', '=', 'users.id')
    ->setBindings([$currentUserId])
    ->get();

必要的模型关联配置

确保你的 Eloquent 模型配置了正确的关联关系:

User 模型

class User extends Model
{
    public function posts()
    {
        return $this->hasMany(Post::class);
    }

    public function postLikes()
    {
        return $this->hasMany(PostLike::class);
    }
}

Post 模型

class Post extends Model
{
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function postLikes()
    {
        return $this->hasMany(PostLike::class);
    }
}

PostLike 模型

class PostLike extends Model
{
    public function post()
    {
        return $this->belongsTo(Post::class);
    }

    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 22:03:24