【问题标题】:Working with Eloquent, How to select popular comments使用 Eloquent,如何选择热门评论
【发布时间】:2013-11-14 14:15:18
【问题描述】:

我是一名试图在这里学习编码的设计师,而 Laravel 非常棒,它让像我这样的设计能够创造出自己微笑的东西

关于我的问题,我遵循了一些教程,现在我学习构建简单的博客系统。 所以我有 Post 模型,它与 $this->morphMany('Like','likeable','likeable_type'); 和 Like 模型有关系。 到目前为止一切都很好。现在我希望能够创建“热门帖子”页面,该页面基本上显示按受欢迎程度排序的帖子,在我的例子中是喜欢的数量。

“喜欢”表有这些字段id | likable_id | likeable_type

  • 'likeable_type',在这种情况下,是'Post'
  • 'likeable_id' 是链接到 'posts' 表中 id 的帖子 id

所以在我的控制器中,我尝试了这个。

$popular_ids = DB::table('likes')
                  ->select('likeable_id')
                  ->groupBy('likeable_id')
                  ->orderBy(DB::raw('COUNT(likeable_id)'), 'DESC')
                  ->get();
$popular_posts = Post::whereIn('id',array_pluck($popular_ids,'likeable_id'))->paginate(15);

这给了我所有热门帖子,但不是我想要的顺序。 我不确定是否有更好的方法来实现这一点,或者我似乎只是错过了另一个 'orderBy' 方法?

对此有何建议?

ps。对不起我的英语不好

【问题讨论】:

    标签: laravel


    【解决方案1】:

    SQL IN 不维护顺序。要实现这一点,必须用户 ORDER BY FIELD('id', , ,...) 来实现这一点。

    $ids = array_pluck($popular_ids,'likeable_id');
    $raw = DB::raw('FIELD(id,' + implode(',', $ids) + ')');
    
    $popular_posts = Post::whereIn('id', $ids)->orderBy($raw)->paginate(15);
    

    更多信息请参考,

    Maintaining order in MySQL "IN" query

    【讨论】:

    • 感谢您抽出宝贵时间分享您的答案 Tharanga。我以前从未听说过FIELD!我今天学到了一些新东西。我从科林的回答中修改了代码,它可以工作。 :)
    【解决方案2】:

    我会通过加入来做到这一点。这有点复杂,但如果你想了解内部结构,你应该阅读 LEFT JOIN 和 INNER JOIN。由于多态关系,这个例子特别难看。

    Post::select('posts.*', DB::raw('COUNT(DISTINCT likes.id) AS popularity'))
        ->leftJoin('likes', function ($join)
        {
            $join->on('likes.likeable_id', '=', 'posts.id')
                ->on('likes.likeable_type', '=', DB::raw("'Post'"));
        })
        ->orderBy('popularity', 'DESC')
        ->paginate(15);
    

    还有一个好处是,人气值现在可以在帖子中使用。

    $post->popularity;
    

    【讨论】:

      【解决方案3】:

      感谢科林抽出宝贵时间!你的回答让我眼前一亮!!!我稍微修改了你的答案,终于得到了我需要的东西。不过,我仍在努力完全理解它。这就是我最终的结果。

      Post::select('posts.*', DB::raw('COUNT(likes.likeable_id) AS popularity'))
         ->join('likes', function($join)
         {
            $join->on('likes.likeable_id', '=', 'posts.id')
                 ->on('likes.likeable_type', '=', DB::raw("'Post'")); 
         })
         ->groupBy('likes.likeable_id')
         ->orderBy('popularity', 'DESC')
         ->paginate(15);
      

      附言。即使这段代码给了我想要的东西,我也不确定我的数据库设计是否正确。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-09
        • 1970-01-01
        • 2014-12-24
        • 1970-01-01
        相关资源
        最近更新 更多