Laravel Eloquent - 查询数据透视表

时间:2018-06-01 14:30:10

标签: php laravel eloquent

在我的Laravel应用程序中,我有三个数据库表,称为用户,项目和角色。它们之间有m:n关系,所以我还有一个名为project_user_role的数据透视表。数据透视表包含user_id,project_id和role_id列。有关MySQL Workbench的截图,请参见图片。

enter image description here

我的用户,项目和角色模型定义了belongsToMany关系:

//User model example
public function projects()
{
    return $this->belongsToMany('App\Library\Models\Project', 'project_user_role')->withPivot(['user_id','role_id']);
}

现在,我可以轻松地获得经过身份验证的用户的项目:

$user = Auth::user();
$projects = $user->projects;

对此的回应如下:

[
  {
      "id": 1,
      "name": "Test project",
      "user_id": 1,
      "created_at": "2018-05-01 01:02:03",
      "updated_at": "2018-05-01 01:02:03",
      "pivot": {
          "user_id": 2,
          "project_id": 17,
          "role_id": 1
      }
  },
]

但是我想将有关用户角色的信息“注入”到响应中:

[
  {
      "id": 1,
      "name": "Test project",
      "user_id": 1,
      "created_at": "2018-05-01 01:02:03",
      "updated_at": "2018-05-01 01:02:03",
      "pivot": {
          "user_id": 2,
          "project_id": 17,
          "role_id": 1
      },
      roles: [
        {
            "id": 1,
            "name": "some role name",
            "display_name": "Some role name",
            "description": "Some role name",
            "created_at": "2018-05-01 01:02:03",
            "updated_at": "2018-05-01 01:02:03",
        }
      ]
  },
]

有可能吗?感谢

2 个答案:

答案 0 :(得分:1)

我想是的,您可以为项目集合加载角色,在项目模型中定义相同的映射

//Project model
public function roles()
{
    return $this->belongsToMany('App\Library\Models\Role', 'project_user_role', 'project_id');
}

在为项目定义的用户模型映射中使用预先加载

public function projects()
{
    return $this->belongsToMany('App\Library\Models\Project', 'project_user_role')
                ->with('roles')
                ->withPivot(['user_id','role_id']);
}

答案 1 :(得分:1)

你基本上要求对数据透视表进行急切加载。问题是,数据透视表中的数据不是来自顶级Model类,因此没有任何关系方法可供您参考。

您的数据库结构也有一点尴尬,因为您的数据透视表正在连接三个表而不是两个表。在实际回答你的问题后,我会对此有所了解......

因此,您可以通过数据透视表从用户转到项目。您可以通过数据透视表从用户转到角色。但是你要找的是通过数据透视表从项目转到角色。 (即您所需的数据报显示项目数据是嵌套'角色'的顶级数据。)。只有在项目模型是您的入口点而不是您的用户时才能执行此操作。

首先,在名为roles的项目模型中添加多对多关系方法,然后像这样运行查询:

app(Projects::class)->with('roles')->wherePivot('user_id', Auth::user()->getKey())->get()

至于结构,我认为你有一点点单一责任违规。 “用户”代表个人。但是你也用它来代表项目“参与者”的概念。我相信您需要一个与User具有多对一关系的新Participant表,以及与Project的一对一关系。然后您的数据透视表只需要参与者和角色之间的多对多,并让用户离开它。

然后您的查询将如下所示:

Auth::user()->participants()->with(['project', 'roles'])->get()

这也使您有机会添加一些数据来描述诸如整个Particip.status是什么,它们何时与该项目关联,何时离开该项目,或者他们的主管(parent_participant_id)可能是谁。 / p>