在 Laravel 中一起使用连接和分页时出现问题
Problems when using join and pagination together in Laravel
我的数据库中有一些 table,我正在尝试在它们之间进行交易。我的目标是在我的项目页面上以卡片的形式显示项目名称和该项目中的员工,如下图所示。 (除了我提到的方法,如果有更好的方法,请大家分享。)
在尝试这样做时,我首先想到的是使用 leftJoin。与项目一起,我想到了将那个项目中的用户拉到一起,并通过使用 foreach 嵌套来显示它们。
如果我只是想拍项目,那没有问题,前 4 个项目来了,一切正常。但由于我需要在该项目中吸引用户以及我的项目,当我使用 leftJoin 时,我得到了如下所示的输出。我不得不使用分页,因为我需要每页显示 4 个项目,并且当我使用分页时,出现的行不一致。在等待4个项目和他们的员工到达时,前4条线来了。 (一个项目的3名员工和另一个项目的第一名员工已到达。)
我的代码:
$query = Project::query();
$query->select('prj_name', 'us_name');
$query->where('up_type_id', 3);
$query->leftJoin('user_positions', 'projects.prj_id', '=', 'user_positions.up_source_id');
$query->leftJoin('users', 'user_positions.up_user_id', '=', 'users.us_id');
$data['projectList'] = $query->paginate(4)->toArray();
return view('pages.projects.index', $data);
输出:
[data] => Array
(
[0] => Array
(
[prj_name] => Project Name - 2
[us_name] => Tracey Dyer
)
[1] => Array
(
[prj_name] => Project Name - 2
[us_name] => Joseph Dickens
)
[2] => Array
(
[prj_name] => Project Name - 2
[us_name] => Steven Ogden
)
[3] => Array
(
[prj_name] => Project Name - 3
[us_name] => Warren Nash
)
)
我的tables:
补充信息:
它与我的问题没有直接关系,但我想说明一下以供参考。我的table名为“user_position_types”代表公司内部的字段。 “user_positions”table中的“up_type_id”列指定分区类型(如Department、Project)。
如果此列为1,则表示部门,“source_id”表示是哪个部门。如果是 3,则表示项目,“source_id”表示它是哪个项目。
谢谢大家提前回答
您可以考虑使用 Eloquent 关系而不是左连接。实际上 left join 在您的情况下效果不佳,因为您必须在之后的行中将同一项目中的所有用户分组。使用 whereHas
和 with
的 Eloquent 关系示例如下。
$data['projectList'] = Project::select('prj_name', 'us_name')
->whereHas('users, function($query) {
$query->where('users_positions.up_type_id', 3);
})
->with('users')
->paginate(4);
whereHas
部分仅过滤具有 users
关系且具有数据透视字段 up_type_id
3.
的项目
而with
部分会加载项目对应的用户。
您还需要在 Project
模型中添加 users
关系。
public function users()
{
return $this->belongsToMany(User::class, 'user_positions', 'prj_id', 'us_id')
->withPivot('up_type_id');
}
有了这个,您可以像这样展示您的项目和用户。
foreach($data['projectList'] as $project) {
$project->prj_name;
foreach($project->users as $user) {
$user->us_name;
}
}
如果您想要没有用户的项目和来自 up_type_id = 3 的用户的项目,您可以使用 where 闭包并从这两个条件进行过滤(使用 orWhereHas
)。
$data['projectList'] = Project::select('prj_name', 'us_name')
->where(function ($query) {
$query->doesntHave('users')
->orWhereHas('users, function($query) {
$query->where('user_positions.up_type_id', 3);
});
})
->with('users')
->paginate(4);
我的数据库中有一些 table,我正在尝试在它们之间进行交易。我的目标是在我的项目页面上以卡片的形式显示项目名称和该项目中的员工,如下图所示。 (除了我提到的方法,如果有更好的方法,请大家分享。)
在尝试这样做时,我首先想到的是使用 leftJoin。与项目一起,我想到了将那个项目中的用户拉到一起,并通过使用 foreach 嵌套来显示它们。 如果我只是想拍项目,那没有问题,前 4 个项目来了,一切正常。但由于我需要在该项目中吸引用户以及我的项目,当我使用 leftJoin 时,我得到了如下所示的输出。我不得不使用分页,因为我需要每页显示 4 个项目,并且当我使用分页时,出现的行不一致。在等待4个项目和他们的员工到达时,前4条线来了。 (一个项目的3名员工和另一个项目的第一名员工已到达。)
我的代码:
$query = Project::query();
$query->select('prj_name', 'us_name');
$query->where('up_type_id', 3);
$query->leftJoin('user_positions', 'projects.prj_id', '=', 'user_positions.up_source_id');
$query->leftJoin('users', 'user_positions.up_user_id', '=', 'users.us_id');
$data['projectList'] = $query->paginate(4)->toArray();
return view('pages.projects.index', $data);
输出:
[data] => Array
(
[0] => Array
(
[prj_name] => Project Name - 2
[us_name] => Tracey Dyer
)
[1] => Array
(
[prj_name] => Project Name - 2
[us_name] => Joseph Dickens
)
[2] => Array
(
[prj_name] => Project Name - 2
[us_name] => Steven Ogden
)
[3] => Array
(
[prj_name] => Project Name - 3
[us_name] => Warren Nash
)
)
我的tables:
补充信息: 它与我的问题没有直接关系,但我想说明一下以供参考。我的table名为“user_position_types”代表公司内部的字段。 “user_positions”table中的“up_type_id”列指定分区类型(如Department、Project)。 如果此列为1,则表示部门,“source_id”表示是哪个部门。如果是 3,则表示项目,“source_id”表示它是哪个项目。
谢谢大家提前回答
您可以考虑使用 Eloquent 关系而不是左连接。实际上 left join 在您的情况下效果不佳,因为您必须在之后的行中将同一项目中的所有用户分组。使用 whereHas
和 with
的 Eloquent 关系示例如下。
$data['projectList'] = Project::select('prj_name', 'us_name')
->whereHas('users, function($query) {
$query->where('users_positions.up_type_id', 3);
})
->with('users')
->paginate(4);
whereHas
部分仅过滤具有 users
关系且具有数据透视字段 up_type_id
3.
的项目
而with
部分会加载项目对应的用户。
您还需要在 Project
模型中添加 users
关系。
public function users()
{
return $this->belongsToMany(User::class, 'user_positions', 'prj_id', 'us_id')
->withPivot('up_type_id');
}
有了这个,您可以像这样展示您的项目和用户。
foreach($data['projectList'] as $project) {
$project->prj_name;
foreach($project->users as $user) {
$user->us_name;
}
}
如果您想要没有用户的项目和来自 up_type_id = 3 的用户的项目,您可以使用 where 闭包并从这两个条件进行过滤(使用 orWhereHas
)。
$data['projectList'] = Project::select('prj_name', 'us_name')
->where(function ($query) {
$query->doesntHave('users')
->orWhereHas('users, function($query) {
$query->where('user_positions.up_type_id', 3);
});
})
->with('users')
->paginate(4);