Laravel Eloquent - 查询数据透视表

Posted

技术标签:

【中文标题】Laravel Eloquent - 查询数据透视表【英文标题】:Laravel Eloquent - querying pivot table 【发布时间】:2018-11-11 17:33:15 【问题描述】:

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

我的用户、项目和角色模型被定义为如下的 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",
        
      ]
  ,
]

有可能吗?谢谢

【问题讨论】:

在用户模型中定义另一个一对多关系。 user 属于角色,并且 rols 有很多用户。并急切地加载`$user->with('role', 'projects') ***.com/q/50460159/4848587 【参考方案1】:

您实际上是在要求对数据透视表进行快速加载。问题是,数据透视表中的数据不是来自***模型类,因此没有任何关系方法可供您参考。

您的数据库结构也有些尴尬,因为您的数据透视表连接了三个表而不是两个。不过,在实际回答您的问题后,我会对此进行一些思考……

因此,您可以通过数据透视表从用户转到项目。您可以通过数据透视表从用户转到角色。但是您正在寻找的是通过该数据透视表从项目转到角色。 (即,您所需的数据报显示项目数据是具有嵌套“角色”的***数据。)。只有当 Projects 模型是您的入口点而不是您的用户时,才能做到这一点。

因此,首先向您的项目模型添加一个名为roles 的多对多关系方法,然后像这样运行您的查询:

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

至于结构,我认为你有一点单一责任违规。 “用户”代表个人。但是您也使用它来表示项目的“参与者”的概念。我相信您需要一个新的 Participant 表,它与 User 具有多对一关系,与 Project 具有一对一关系。那么您的数据透视表只需要在 Participant 和 Role 之间是多对多的,而将 User 排除在外。

那么您的查询将如下所示:

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

这也让您有机会添加一些数据来描述整体参与者的状态、他们何时与该项目相关联、何时离开该项目或他们的主管 (parent_participant_id) 可能是谁。

【讨论】:

非常感谢您的评论。这是有道理的:)我会尝试然后让你知道。 酷,我希望它有所帮助。如果您在那里尝试第二个选项,请注意,我忘记了“->参与者”末尾的括号,错过它们可能会让您感到困惑。刚刚编辑以包含它们。【参考方案2】:

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

//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']);

【讨论】:

以上是关于Laravel Eloquent - 查询数据透视表的主要内容,如果未能解决你的问题,请参考以下文章

Eloquent ORM / Laravel - 使用自定义数据透视表结构

Laravel Eloquent 根据数据透视表字段条件获取多对多关系

Laravel Eloquent:我的数据透视表有关系

Lumen/Laravel Eloquent - 按数据透视表中的属性过滤

laravel 使用 in 子句模型名称连接多态数据透视表

查询 Laravel Eloquent 多对多,其中所有 id 都相等