laravel - Eloquent:在链式 whereHas() 中使用中间表
问题描述
不幸的是,我有一个相对复杂的数据库组织,我无法更改和优化。
长话短说,这里大致是这个数据库的组织,与我的问题相关:
user
→ hasMany → role_assignments
→ belongsTo → context
→ belongsTo (其实是一个morphTo) → course
→ hasMany → enrol
→ hasMany → user_enrolments
→ belongsTo →user
所有这些模型都有自己的资源,目前我正在尝试将所有用户作为一个集合,例如:
user
→ 多个与 → course
→ 与 → enrol
→where('user_enrolments.userid', 'user.id')
这是我的UserController.php
:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Resources\userResource;
use App\Models\user;
use Illuminate\Http\Request;
class userController extends Controller
{
public function index()
{
return new userResource::collection(
user::query()
->where(function ($q) {
$q
->whereHas('role_assignments', function ($q) {
$q->
->where('role', 'student')
->whereHas('context', function ($q) {
$q->whereHas('course', function ($q) {
$q->whereHas('enrol', function ($q) {
// And this is where I don't know what to do.
// I think it should look like:
$q->whereHas('user_enrolments', function ($q) {
$q->where('userid', 'user.id');
});
});
});
});
})
->with([
// ...
}])
->get()
);
}
所以,我真的不知道该怎么办!
在此先感谢您的帮助。
编辑:
在Alex T 的回答之后,我觉得我需要精确一些东西。
首先,我->where('role', 'student')
在上面的代码中添加了这行代码,让它看起来更像我自己的代码。当我第一次发布时,我试图略读它以使其更具可读性并专注于我当前的问题,但我可能略读它太多了。对于那个很抱歉。
我可以很容易地找到用户的所有课程,无论是通过用户的注册,还是通过他的角色分配。但我需要这两个中间表中的信息。理想情况下,我的 Controller 将返回以下 JSON 示例:
[
{
id: 1,
name: "exampleUser1",
otherInfoAboutThisUser: "...",
role_assignmentsWhereTheUserIsAStudent:
[
{
id: 357,
role: "student",
courseid: 1000,
course:
{
id: 1000,
name: "Course Example",
user_enrolmentConcerningOnlyUser1:
{
id: 9,
timestart: 1540974600,
duration: 3600,
userid: 1
}
}
},
{
otherRoleAssignmentsWithTheirCourses...
},
]
},
{
otherUserWithHisOwnCharacteristics...
}
]
解决方案
如果我正确理解了您的问题,您希望获得所有注册至少一门课程的用户。
enrol
在这种情况下,我将使用 Laravel 的查询关系存在查询构建器来构建我的查询以获取至少拥有一个 的用户,并假设 anerol
意味着他们已注册课程。
您只需要whereHas
在需要对关系存在的查询进行更多控制时使用 - 根据上面的代码,您似乎没有对此设置任何条件。
如果您只是想让用户注册至少一门课程,您的查询将采用以下形式:
$query = user::has('enrols')
->with([...])
->get([...])
如果您需要用户注册,例如,作为特定课程,您可以执行以下操作:
$query = user::whereHas('enrols', function ($query) {
// Assuming you have a 'courseid' key on your enrols table
$query->where('courseid', $requestedCourseId);
})
->with([...])
->get([...])
在您的user
模型上,您的enrols
关系定义为:
public function enrols()
{
return $this->belongsToMany(Enrol::class, 'user_enrolments', 'userid', 'enrolid';
}
这使用您的user_enrolments
which 本质上用作多对多关系的数据透视表。
推荐阅读
- navbar - Intersection Observer - 突出显示当前部分
- java - Spring MVC项目中的多个请求关闭OutputStream
- solr - AKS custom log log analytics
- python - 比较两个 CSV 文件之间的日期时间对象时出现循环问题
- javascript - 将 LocalStorage 中的 JSON 文件解析为 react-native
- logstash - Difference between remove_field in drop filter plugin and remove_field in mutate filter plugin
- javascript - 自动完成从数据库输出两个字段
- dask - Dask 上的 Jupyter Hub 使用内部负载平衡器
- r - 多变量相关性错误 - “一些多变量变量的类别少于应有的类别”
- spring-boot - 将 Spring Boot DataSource 配置迁移到 Hikari CP