带有条件语句的 Laravel Eager Load

Posted

技术标签:

【中文标题】带有条件语句的 Laravel Eager Load【英文标题】:Laravel Eager Load with conditional statement 【发布时间】:2021-05-04 17:09:54 【问题描述】:

大家好

我是 Laravel 的新手,目前正在用它构建我的第一个简单的新闻应用程序

我有一个使用 laravel 的急切加载功能的简单查询 但是在这个急切的加载功能中,我想根据某些条件获取某些 cmets

例子:

use App\News;
...

public function home() 
    $news = News::with([
                    'thumbnail',
                    'source', // link to real news source
                    'comments' => function ($query) 
                        // fetch a comment where likes > 0, otherwise, get latest comment
                        // *get only one*
                    
                ])->paginate(5);

    return response()->json([
        'news' => $news
    ]);

如何做到这一点?

更新

我找到了一种按点赞数排序 cmets 的方法,但如果每条评论中都没有点赞,我不知道如何按“created_at”(获取最新评论)对它们进行排序

我需要使用withCount('likes') 包含“likes_count” 然后按降序排列

public function home() 
    $news = News::with([
        'thumbnail',
        'source',
        'comments' => function ($query) 
            $query->withCount('likes');
            $query->orderBy('likes_count', 'DESC')->first();

            // return the first comment that has likes or most liked comment
        
    ])->paginate(5);

    ...

如果 cmets 中没有类似的,现在如何通过“created_at”(最新的)将后备查询用于订购 cmets?

提前致谢

【问题讨论】:

添加另一个订单 by created at desc 所以如果所有 cmets 有 0 个赞,那么最新的将出现在列表的第一位,如果 cmets 有赞,那么它们也使用 created at 排序 你说的对,谢谢指点 我必须输入 2 个查询 orderBy() 一个是 likes_count,另一个是 created_at $query->orderBy('likes_count', 'DESC')->first(); $query->orderBy('created_at', 'DESC')->first(); 我已经通过多次删除和恢复评论上的赞来测试它并且它正在工作并且btw,你会回答我的问题吗?如果你是,我会把你的答案标记为正确的,否则我会再回答一次,谢谢 【参考方案1】:

您当前的方法看起来很适合按点赞数排序结果,如果没有点赞,您仍然可以通过使用 created_at 列添加另一个 order by 子句来获得最新记录

$news = News::with([
    'thumbnail',
    'source',
    'comments' => function ($query) 
        $query->withCount('likes');
        $query->orderBy('likes_count', 'DESC')
              ->orderBy('created_at', 'DESC');
    
])->paginate(5);

从最初的评论复制

因此,如果所有 cmets 都有 0 个赞,那么最新的将出现在列表中的第一位,如果 cmets 有赞,那么它们也会先按赞数排序,然后按创建时间排序。

一旦您订购了集合,然后在您循环播放新闻记录时,然后从相关记录中选择第一项

【讨论】:

顺便说一句,我有一个简单的问题,将这些 queryBy 放在一起并将它们分成 2 行之间有什么区别吗? @ChristianDelvianto 没有;差别不大,在同一行做基本上叫做方法链 @ChristianDelvianto 我已经更新了我的答案,使用First() 将只返回一条评论,因此您需要加载所有按喜欢计数/创建时间排序的 cmets,而当您显示时新闻然后从排序的评论集合中选择第一条记录,干杯

以上是关于带有条件语句的 Laravel Eager Load的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Eloquent Eager Loading:加入同一张表两次

Laravel Eloquent Where and or Where with Eager Load 无法正常工作

Laravel:如何设置带有条件的自定义列?

Laravel - Eager Loading BelongsToMany 关系

Laravel 通过 Eager 加载获取 Join 表中的最新字段

刀片视图:带有 OR/AND 条件的 if 语句