【问题标题】:Combine two eloquent collections into single collection and paginate将两个 eloquent 集合合并为一个集合并分页
【发布时间】:2023-03-07 23:17:01
【问题描述】:

我有一个新闻网站,其中包含主页上帖子的概述。带有分页的简单 Eloquent 集合,说实话没什么特别的(模型 = 帖子)。 现在添加了一个新模型(视频),应该将其添加到主页上的帖子概述中。

所以我们的目标是获得一个有说服力的帖子集合和一个有说服力的视频集合(它们彼此不相关),然后将它们组合成一个集合并对其进行分页。

我环顾四周并尝试了几件事,但似乎都没有奏效。 大多数时候,他们说要使用$collection->merge($otherCollection),但这不起作用,因为如果有相同 id 的帖子,则不会显示 id 为 1 的视频,情况就是这样。

另一种选择是定义关系,但由于它们根本不相关,因此也不起作用。

我目前所拥有的,只是为了获取帖子:

if ($highlighted) {
    $posts = Post::where([
        ['status_id', '=', 4],
        ['published_at', '<=', Carbon::now()],
        ['id', '!=', $highlighted->id],
     ])->latest('published_at')->paginate(14);
} else {
     $posts = Post::where([
         ['status_id', '=', 4],
         ['published_at', '<=', Carbon::now()]
     ])->latest('published_at')->paginate(15);
}

现在我想以类似的方式检索视频

$videos = Video::where([
    ['status_id', '=', 4],
    ['published_at', '<=', Carbon::now()]
])->latest('published_at')->paginate(15);

然后将它们合并到一个 Eloquent 集合中,并对总数进行分页,而不是单独对视频和帖子进行分页

类似: $collected = $videos + $posts 然后-&gt;latest('published_at')-&gt;paginate(15)

(为了这篇文章的篇幅,我没有添加任何我尝试过的示例,因为我觉得这不是要走的路,使用-&gt;merge()。我还需要一个雄辩的集合,使用纯数据库查询不起作用,除非可以将其转换为 Eloquent 集合)

也许雄辩的集合不可能,我应该使用查询生成器?

非常感谢任何反馈/帮助。 (请随时询问额外的代码/信息)

【问题讨论】:

  • 您是否尝试过运行两个查询并将它们组合成一个数组?然后只循环遍历刀片上的数组?
  • 这就是问题所在。 paginate 将运行 2 个查询。 1)计算总预期结果(因此知道有多少总页面和2)当前页面的实际查询(默认为第一个)。这是像您这样的联合类型查询的问题,因此您的选择是(a)手动创建查询以计算所有结果的长度,然后使用 union 和限制进行另一个手动查询,然后手动创建基于 LengthAwarePaginator 对象结果或(b)stackoverflow.com/questions/30420505/…

标签: php laravel eloquent


【解决方案1】:

您可以发送两个不同的查询,将两个结果合并到Illuminate\Support\Collection,然后sortBy('published_at'),然后使用skip(($numPage - 1) * $perPage)limit($perPage) 进行分页。

如果有帮助请告诉我

【讨论】:

    【解决方案2】:

    感谢此处发布的 cmets 和答案,我设法找到了一个似乎可行的解决方案:

    为了检索数据,我执行了以下操作:

    $posts = Post::where([
        ['status_id', '=', 4],
        ['published_at', '<=', Carbon::now()]
    ])->get();
    $videos = Video::where([
        ['status_id', '=', 4],
        ['published_at', '<=', Carbon::now()]
    ])->get();
    
    $collected = $videos->union($posts)->sortByDesc('published_at');
    

    正如对此问题的评论中所述:https://stackoverflow.com/a/30421846/4666299 我使用https://gist.github.com/simonhamp/549e8821946e2c40a617c85d2cf5af5e 进行分页。

    这样我就可以这样做了:

    $items = (collect($collected))->paginate(15);
    

    现在我有一个可以在 Blade 中循环的集合。 感谢大家的帮助!

    猜你喜欢
    • 2015-08-11
    • 2014-05-29
    • 2011-11-24
    • 2017-04-12
    • 1970-01-01
    • 2015-10-20
    • 2019-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多