通过条件过滤一个关系并急切加载另一个关系记录

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_idschool_id(一种枢轴 table)的列,其中每条记录可以由 ['user_id', school_id'] 复合键唯一标识 - 数据库 table.

上的唯一索引

然后你可以定义UserSchool

之间的直接(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]);
}

Laravel Docs - Eloquent Relationships - Many-to-Many