首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Laravel雄辩查询数据透视表

Laravel雄辩查询数据透视表
EN

Stack Overflow用户
提问于 2018-06-01 22:30:10
回答 2查看 15.9K关注 0票数 2

在我的Laravel应用程序中,我有三个数据库表,分别为users、projects和roles。它们之间有m:n的关系,所以我也有一个叫做project_user_role的透视表。透视表包含user_id、project_id和role_id列。请参阅来自MySQL工作台的屏幕截图。

我的用户、项目和角色模型的belongsToMany关系定义如下:

代码语言:javascript
复制
//User model example
public function projects()
{
    return $this->belongsToMany('App\Library\Models\Project', 'project_user_role')->withPivot(['user_id','role_id']);
}

现在我可以很容易地获得认证用户的项目,如下所示:

代码语言:javascript
复制
$user = Auth::user();
$projects = $user->projects;

下面的响应是这样的:

代码语言:javascript
复制
[
  {
      "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
      }
  },
]

但我想将有关用户角色的信息“注入”到响应中,如下所示:

代码语言:javascript
复制
[
  {
      "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",
        }
      ]
  },
]

有可能吗?谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-01 22:59:37

您实际上是在请求一个数据透视表上的急切加载。问题是,数据透视表中的数据不是来自顶级的Model类,所以没有任何关系方法可供您引用。

在DB结构中也有一点笨拙,因为您的数据透视表连接了三个表而不是两个表。不过,在实际回答你的问题之后,我会对此进行一些思考的。

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

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

代码语言:javascript
复制
app(Projects::class)->with('roles')->wherePivot('user_id', Auth::user()->getKey())->get()

至于结构,我认为你有一点单一责任的违反。"User“代表一个单独的人。但您也可以使用它来表示项目的“参与者”的概念。我认为您需要一个新的Participant表,它与User具有多对一的关系,与Project具有一对一的关系。那么您的数据透视表只需要是Participant和Role之间的多对多,并且不需要User。

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

代码语言:javascript
复制
Auth::user()->participants()->with(['project', 'roles'])->get()

这还将使您有机会添加一些数据,描述总体participant.status是什么,他们何时与该项目相关联,他们何时离开该项目,或者他们的主管(parent_participant_id)可能是谁。

票数 5
EN

Stack Overflow用户

发布于 2018-06-01 22:42:14

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

代码语言:javascript
复制
//Project model
public function roles()
{
    return $this->belongsToMany('App\Library\Models\Role', 'project_user_role', 'project_id');
}

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

代码语言:javascript
复制
public function projects()
{
    return $this->belongsToMany('App\Library\Models\Project', 'project_user_role')
                ->with('roles')
                ->withPivot(['user_id','role_id']);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50645723

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档