首页 > 解决方案 > 是否可以在单个 Eloquent 查询中生成 3 个嵌套层?

问题描述

我正在尝试为 Vue 前端的 Ajax 响应生成 json 以表示反应系统,输出类似于您在 Facebook 中看到的输出。帖子具有反应类型(例如,爱,愤怒),并且这些反应类型中的每一种都会有已注册该反应的用户。

我正在寻找的输出是为了将大部分工作保留在控制器中,这样前端就不必循环输出来总计计数,如下所示:

[
  {
    "id": 258,
    "reactions": [
      {
        "type": "like",
        "count": 2,
        "names": [
          {
            "user_id": 1,
            "first_name": "Drew",
          },
          {
            "user_id": 2,
            "first_name": "Kathy",
          }
        ]
      },
      {
        "type": "angry",
        "count": 3,
        "names": [
          {
            "user_id": 3,
            "first_name": "Bob",
          },
          {
            "user_id": 4,
            "first_name": "Fred",
          },
          {
            "user_id": 5,
            "first_name": "Anne",
          }
        ]
      }
    ],
  }
] 

我可以很容易地得到前两层:

return Post::latest()
    ->with('user:id,first_name')
    ->with(['postReactions' => function($query) {
        $query->select(DB::table('post_reactions'))
            ->select('post_id', 'type', DB::raw('count(*) as count'))
            ->groupBy('post_id', 'type');
    }])

而且我已经能够使用二级细节但没有摘要计数来完成它的各种版本。

在我的脑海中,我想在 postReactions 子查询中添加一个嵌套的“with”,例如:

return Post::latest()
    ->with('user:id,first_name')
    ->with(['postReactions' => function($query) {
        $query->select(DB::table('post_reactions'))
            ->select('post_id', 'type', DB::raw('count(*) as count'))
            ->groupBy('post_id', 'type');
        $query->with('user:id,first_name');
    }])

这是可能的还是我需要遍历我的初始结果以添加名称详细信息?

标签: jsonlaravelvue.js

解决方案


有内置的withCount()方法供您使用。

至于嵌套关系,如果您使用点约定链接嵌套关系,它们将获得您想要的结构:

->with('reactions.names')

当然,我假设这些是您关系的实际名称。


推荐阅读