按照 created_at 对 Eloquent 集合进行排序。

33

我有一张名为“posts”的表格,包含以下列:“post_id int primary increments”、“poster_id int”和“status text”,还有一个名为“friends”的数组,包括以下列:“user_id int primary”和“friend_ids text”。

我需要获取在“friends”的文本列中的所有ID,这很容易使用以下方法:

$friends = explode(',', \Friend::where('user_id', \Sentry::getUser()->id)->first()->friend_ids);

文本列中的数据看起来像 '1,2,3,' 等。

然后,我创建一个 Eloquent Collection 对象,这也可以很容易地通过以下方式完成:

$posts = new \Illuminate\Database\Eloquent\Collection();

但问题是我无法弄清楚如何填充集合并按照帖子对象的“created_at”列对其内容进行排序。

目前我的代码如下:

foreach ($friends as $id) {
    $posts_ = \Post::where('poster_id', $id)->getQuery()
        ->orderBy('created_at', 'desc')
        ->get();
    foreach($posts_ as $post) {
        $posts->add($post);
    }
}

我无法确定这段代码是否可以按照“created_at”列对所有文章进行排序,同时我也需要能够轻松地对整个集合进行分页。

什么是推荐的集合排序方式?

5个回答

72

如果你想对一个collection进行排序,你可以使用sortBy方法并指定键值

$sorted = $posts->sortBy('created_at');

同时,您还可以在collection上应用回调函数。

$sorted = $posts->sortBy(function($post)
{
  return $post->created_at;
});

希望这对您有所帮助。如需了解更多有关 collections 的信息,您可以阅读文档


1
太棒了!☺ 对于我的情况,我有更多的维度,所以我将其改为 return $post->type->hierarchy;,然后它就能工作了! - Pathros
我该如何按多个字段排序?(我的意思是,当某个字段的值相同时,按其他标准进行排序) - JCarlosR
1
@shock_gone_wild 它按照创建时间字符串进行排序,但比较仍然可以正确进行。如果您希望,还可以转换为Unix时间戳return strtotime($post->created_at); - Altrim
1
感谢您的回答。只要格式为Y-m-d,它就可以工作。但是,如果created_at的格式不是按最重要的时间段排序,例如m.d.Y,排序顺序将会失败。但是使用strtotime()函数,它将在任何情况下都能正常工作。 - shock_gone_wild
@shock_gone_wild 是的,你说得对,我假设使用 Laravel 用于时间戳的默认格式。但为了确保,请使用 strtotime()。 - Altrim
显示剩余2条评论

9
你不需要遍历 $friends 数组,只需要将它与 whereIn 一起使用即可,如下所示。
$posts = \Post::whereIn('poster_id', $friends)->latest()->get();

这将替换空集合创建和foreach循环,并为您提供按created_at排序的所有好友帖子的整个集合。(latest函数是orderBy('created_at', 'desc')的快捷方式)

1
在Laravel 8中,可以像这样实现带分页的排序:
$sorted = $posts->sortBy('created_at');

0
两种最简单的排序方式。
升序排序: $posts->sortBy('created_at') 降序排序: $posts->sortByDesc('created_at')

0
如果你想获取最新添加的帖子,你可以简单地使用“反转函数”:
$sorted = $posts->sortBy('created_at')->reverse();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接