通过条件过滤一个关系并急切加载另一个关系记录
Filter via condition on one relation and eager load another relation records
我有这段代码我想获得具有教师角色的列表用户,其中每位教师将有一个对象用于个人详细信息,一个对象用于学校详细信息
public function index(){
$teachers = User::whereHas('roles' , function($q){$q->where('name','isTeacher');})->get();
foreach($teachers as $teacher){
$teacher_id = $teacher->id;
$teacherinSchool = School_Teachers::where('user_id', $teacher_id)->first();
$teacherinSchool = $teacherinSchool->school_id;
$School = School::where('id', $teacherinSchool)->first();
return response(['teacher'=>$teacher, 'school'=>$School]);
}
}
这就是我得到的,但我希望有更多的老师,但它需要列表中的第一位老师并显示对象
output in the postman
我这里涉及 5 个模型用户模型、角色模型、User_Role 模型、学校模型和 school_teacher 模型
需要指出的几点
- 您正在循环中执行查询 (foreach) 不利于性能。
- 在 foreach 循环中有
return response()
,因此只有 1 条教师记录可用
- 您正在获得 School_Teachers & School
的第一条记录
对于您正在尝试做的事情,可以更有效地完成
public function index()
{
$teachers = User::whereHas('roles', fn($query) => $query->where('name', 'isTeacher'))->get();
$schoolIds = School_Teachers::whereIn('user_id', $teachers->pluck('id')->toArray())->pluck('id')->toArray();
$schools = School::whereIn('id', $schoolIds)->get();
return response()->json(['teachers' => $teachers, 'schools' => $schools]);
}
不过那也不是最优的,还可以更好
- 通过
School_Teachers
(many-to-many) 定义 User
模型到 link 到 School
模型的关系
- 然后在单个查询中,您可以获得
User
(s),它们具有 isTeacher
的角色以及 School
例如:假设您有一个 table school_teachers
,其中包含 user_id
、school_id
(一种枢轴 table)的列,其中每条记录可以由 ['user_id', school_id']
复合键唯一标识 - 数据库 table.
上的唯一索引
然后你可以定义User
和School
之间的直接(many-to-many)关系
//User model
public function schools()
{
return $this->belongsToMany(School::class, 'school_teachers', 'user_id', 'school_id');
}
//School model
public function teachers()
{
return $this->belongsToMany(User::class, 'school_teachers', 'school_id', 'user_id');
}
在控制器中你可以做
public function index()
{
$teachers = User::with('schools')
->whereHas(
'roles',
fn($query) => $query->where('name', 'isTeacher')
)
->get();
return response()->json(['teachers' => $teachers]);
}
我有这段代码我想获得具有教师角色的列表用户,其中每位教师将有一个对象用于个人详细信息,一个对象用于学校详细信息
public function index(){
$teachers = User::whereHas('roles' , function($q){$q->where('name','isTeacher');})->get();
foreach($teachers as $teacher){
$teacher_id = $teacher->id;
$teacherinSchool = School_Teachers::where('user_id', $teacher_id)->first();
$teacherinSchool = $teacherinSchool->school_id;
$School = School::where('id', $teacherinSchool)->first();
return response(['teacher'=>$teacher, 'school'=>$School]);
}
}
这就是我得到的,但我希望有更多的老师,但它需要列表中的第一位老师并显示对象
output in the postman
我这里涉及 5 个模型用户模型、角色模型、User_Role 模型、学校模型和 school_teacher 模型
需要指出的几点
- 您正在循环中执行查询 (foreach) 不利于性能。
- 在 foreach 循环中有
return response()
,因此只有 1 条教师记录可用 - 您正在获得 School_Teachers & School 的第一条记录
对于您正在尝试做的事情,可以更有效地完成
public function index()
{
$teachers = User::whereHas('roles', fn($query) => $query->where('name', 'isTeacher'))->get();
$schoolIds = School_Teachers::whereIn('user_id', $teachers->pluck('id')->toArray())->pluck('id')->toArray();
$schools = School::whereIn('id', $schoolIds)->get();
return response()->json(['teachers' => $teachers, 'schools' => $schools]);
}
不过那也不是最优的,还可以更好
- 通过
School_Teachers
(many-to-many) 定义 - 然后在单个查询中,您可以获得
User
(s),它们具有isTeacher
的角色以及School
User
模型到 link 到 School
模型的关系
例如:假设您有一个 table school_teachers
,其中包含 user_id
、school_id
(一种枢轴 table)的列,其中每条记录可以由 ['user_id', school_id']
复合键唯一标识 - 数据库 table.
然后你可以定义User
和School
//User model
public function schools()
{
return $this->belongsToMany(School::class, 'school_teachers', 'user_id', 'school_id');
}
//School model
public function teachers()
{
return $this->belongsToMany(User::class, 'school_teachers', 'school_id', 'user_id');
}
在控制器中你可以做
public function index()
{
$teachers = User::with('schools')
->whereHas(
'roles',
fn($query) => $query->where('name', 'isTeacher')
)
->get();
return response()->json(['teachers' => $teachers]);
}