我有帖子表和评论表,评论属于帖子,我在帖子和评论模型中设置了关系。我根据每个帖子的评论数量对帖子进行排序,如下所示:
$posts = Post::with('comments')->get()->sortBy(function($post) {
return $post->comments->count();
});
我想知道如何分页这些排序的帖子?
$posts = Post::with('comments')->get()->sortBy(function($post) {
return $post->comments->count();
})->paginate(20);
不起作用,并且给出了错误,指出paginate是一种未定义的方法。
答案 0 :(得分:5)
我不知道你是否可以使用Eloquent来做,但你可以使用join来实现:
$posts = Post::leftJoin('comments','posts.id','=','comments.post_id')->
selectRaw('posts.*, count(comments.post_id) AS `count`')->
groupBy('posts.id')->
orderBy('count','DESC')->
paginate(20);
然而,在这种情况下,似乎所有记录都是从数据库中获取的,并且只显示来自paginator的记录,所以如果你有很多记录,那就浪费了资源。看来你应该为此做手工分页:
$posts = Post::leftJoin('comments','posts.id','=','comments.post_id')->
selectRaw('posts.*, count(comments.post_id) AS `count`')->
groupBy('posts.id')->
orderBy('count','DESC')->
skip(0)->take(20)->get();
使用skip
和take
,但我不是Eloquent专家,也许有更好的解决方案来实现您的目标,这样您就可以等待,也许有人会给出更好的答案。
答案 1 :(得分:1)
这听起来很明显,但Eloquent不会在此处返回结果集,而是会返回一个集合。
如果您深入了解来源(Builder::get
来电Builder::getFresh
,其中会拨打Builder::runSelect
来拨打Connection::select
),您会发现它已经发现了/**
* Run a select statement against the database.
*
* @param string $query
* @param array $bindings
* @param bool $useReadPdo
* @return array
*/
public function select($query, $bindings = array(), $useReadPdo = true)
{
return $this->run($query, $bindings, function($me, $query, $bindings) use ($useReadPdo)
{
if ($me->pretending()) return array();
// For select statements, we'll simply execute the query and return an array
// of the database result set. Each element in the array will be a single
// row from the database table, and will either be an array or objects.
$statement = $this->getPdoForSelect($useReadPdo)->prepare($query);
$statement->execute($me->prepareBindings($bindings));
//** this is a very basic form of fetching, it is limited to the PDO consts.
return $statement->fetchAll($me->getFetchMode());
});
}
。的目的是简单地返回结果,然后将结果放入集合(具有sortBy方法)。
$posts = Post::leftJoin('comments','posts.id','=','comments.post_id')->
selectRaw('posts.*, count(comments.post_id) AS `count`')->
groupBy('posts.id')->
orderBy('count','DESC')->
skip(0)->take(20)->get();
如果您希望在不加载每个项目的情况下进行分页,那么您需要使用@ Marcin的解决方案(下面重复):
{{1}}
答案 2 :(得分:0)
只需删除链式调用中的get()
,看看你得到了什么,paginate应该替换get()调用。