1

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

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

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

  • 在这种情况下,“likeable_type”是“发布”
  • '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”方法?

对此有何建议?

附言。对不起我的英语不好

4

3 回答 3

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;
于 2013-11-15T05:58:01.327 回答
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);

有关更多信息,请参阅,

维护 MySQL“IN”查询中的顺序

于 2013-11-14T23:00:31.893 回答
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);

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

于 2013-11-20T13:09:51.607 回答