使用Eloquent,如何选择热门评论

时间:2013-11-14 14:15:19

标签: laravel

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

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

“赞”表中包含以下字段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。抱歉我的英语不好

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

我会通过加入来做到这一点。这有点复杂,但如果你想了解内部,你应该读入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;

答案 2 :(得分:0)

谢谢科林的时间!你的回答引导我走向光明!我稍微修改了你的答案,最后得到了我需要的东西。我仍然试图完全理解它。这就是我最终的结果。

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);

聚苯乙烯。即使这段代码给了我想要的东西,我也不确定我的数据库设计是否合适。