php - 按最新(最近)相关模型排序 [Laravel]

标签 php sql laravel laravel-5 laravel-eloquent

我正在使用 Laravel 5.4,我有以下关系:

  • 论坛hasMany线程 ( threads() )
  • 主题 hasMany发帖 ( posts() )
  • 主题 belongsTo用户 ( user() )
  • 发帖 belongsTo用户 ( user() )

  • 目前,在我的 ThreadsController@index 中我有以下几点:
    public function index()
    {
        $threads = $this->forum->threads()
            ->approved()
            ->withCount(['posts AS approved_replies' => function ($query) {
                $query->where('posts.approved', true)->where('posts.is_starting_thread', false);
            }])
            ->with(['posts' => function ($query) { // Posts
                $query->approved()
                    ->with('user') // Author of post
                    ->latest();
                }]
            )
            ->with('user') // Author of thread
            ->latest()
            ->paginate(20); 
    
        return view('forums.threads.index')->with([
            'forum' => $this->forum, 'threads' => $threads
        ]);
    }
    

    我的 index.blade.php应该显示 的列表线程 对于每个线程,其中将有:
  • 它的作者(这就是为什么我有 ->with('user'))
  • 回复数量(这就是为什么我有 >withCount(['posts AS approved_replies' => function ($query) { ... )
  • 最新(最新)帖子及其作者的日期。这就是为什么:
        ->with(['posts' => function ($query) { // Posts
            $query->approved()
                ->with('user') // Author of post
                ->latest(); // LATEST first
            }]
        )
    

    ... 因为然后在 index.blade.php我可以通过以下方式访问每个线程的最新帖子:
    @foreach ($threads as $thread) 
        {{ $thread->posts->first()->created_at; }}
        {{ $thread->posts->first()->user->username; }}
    @endforeach 
    

  • 这段代码的问题在于线程是按它们的 created_at 排序的。 ,不是最近的帖子。我想要实现的是按最新(最近的)帖子订购线程,但我不知道如何执行此操作。

    最佳答案

    这就是我要怎么做。它不是特别漂亮,但应该可以完成这项工作

    $this->forum->threads()
        ->approved()
        ->join('posts', 'posts.thread_id', '=', 'threads.id')
        ->selectRaw('threads.*, MAX(posts.created_at) AS latest_post_at')
        ->groupBy('threads.id')
        ->orderByDesc('latest_post_at')
        ->withCount(['posts AS approved_replies' => function ($query) {
            $query->where('posts.approved', true)->where('posts.is_starting_thread', false);
        }])
        ->with(['posts' => function ($query) { // Posts
            $query->approved()
                ->with('user') // Author of post
                ->latest();
            }]
        )
        ->with('user')
        ->paginate(20);
    

    它做了一个 join正如另一个答案所暗示的那样,然后 groups通过线程,使用 MAX聚合函数以保留每组帖子的最新日期。

    编辑:
    $this->forum->threads()
        ->approved()
        ->join('posts', 'posts.thread_id', '=', 'threads.id')
        ->select('threads.*', 'posts.created_at AS latest_post_at')
        ->whereNotExists(function ($subquery) {
            return $subquery->from('posts AS later_posts')
                ->whereRaw('later_posts.thread_id = posts.thread_id')
                ->whereRaw('later_posts.created_at > posts.created_at');
        })
        ->orderByDesc('latest_post_at')
        ->withCount(['posts AS approved_replies' => function ($query) {
            $query->where('posts.approved', true)
                  ->where('posts.is_starting_thread', false);
        }])
        ->with(['posts' => function ($query) { // Posts
            $query->approved()
                ->with('user') // Author of post
                ->latest();
        }])
        ->with('user')
        ->paginate(20);
    

    关于php - 按最新(最近)相关模型排序 [Laravel],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47965726/

    相关文章:

    mysql - 子查询返回了 1 个以上的值。当子查询跟在 =, !=, , >= 之后或者当子查询用作 expr 时,这是不允许的

    具有 Restful Laravel 嵌套 Controller

    php - 向 Blade 中的日期字段添加三个小时

    PHP 验证码 CAPTCHA

    php - SQL php在不同页面上插入(mysqli)

    php - 将复选框数组值添加到 MySQL 数据库中的多行中

    sql - Postgres 将字符变化视为整数

    php - 在 Laravel 7 中返回响应图像

    php - 如何将 Pusher Laravel Echo 与 SharedWorkers 一起使用?

    php - 没有正则表达式的英国 (GB) 邮政编码验证