Laravel多角色模型关联及认证用户关联学生查询方案
User/Staff/Parent/Student 多模型关联查询方案
预设关联规则
- Staff、Parent、Student三类身份均绑定一个User系统账号
- Staff可同时兼任Parent身份,Parent也可同时为Staff
- Student与Parent为双向
belongsToMany多对多关联
现有模型代码
App\Models\Student.php
protected $fillable = [ 'name', 'email', 'student_user_id', 'created_at', 'updated_at', 'deleted_at', ]; public function student_user() { return $this->belongsTo(User::class, 'student_user_id'); } public function guardians() { return $this->belongsToMany(StudentGuardian::class); }
App\Models\StudentGuardian.php(Parent家长模型)
protected $fillable = [ 'name', 'email', 'guardian_user_id', 'is_staff', 'guardian_staff_id', 'created_at', 'updated_at', 'deleted_at', ]; public function students() { return $this->belongsToMany(Student::class); } public function guardian_user() { return $this->belongsTo(User::class, 'guardian_user_id'); } public function guardian_staff() { return $this->belongsTo(Staff::class, 'guardian_staff_id'); }
App\Models\Staff.php
protected $fillable = [ 'name', 'email', 'staff_user_id', 'staff_guardian_id', 'is_student_guardian', 'created_at', 'updated_at', 'deleted_at', ]; public function staff_user() { return $this->belongsTo(User::class, 'staff_user_id'); } public function staff_guardian() { return $this->belongsTo(StudentGuardian::class, 'staff_guardian_id'); }
待解决问题
在StudentsController中编写查询逻辑,获取与已认证用户(authenticated user)相关联的学生数据。
实现步骤
- 先补全User模型的身份关联,方便后续快速判断当前登录用户的身份类型,在
App\Models\User.php中新增以下方法:
// 关联学生身份档案 public function studentProfile() { return $this->hasOne(Student::class, 'student_user_id'); } // 关联家长身份档案 public function guardianProfile() { return $this->hasOne(StudentGuardian::class, 'guardian_user_id'); } // 关联教职工身份档案 public function staffProfile() { return $this->hasOne(Staff::class, 'staff_user_id'); }
- 在
StudentsController中编写查询逻辑,覆盖所有身份场景的关联学生:
// 获取当前已认证用户 $currentUser = auth()->user(); // 初始化学生查询构造器 $studentQuery = Student::query(); // 场景1:当前用户本身是学生,加入自身数据 if ($currentUser->studentProfile) { $studentQuery->orWhere('id', $currentUser->studentProfile->id); } // 场景2:当前用户是家长,加入所有关联的子女数据 if ($currentUser->guardianProfile) { $guardianStudentIds = $currentUser->guardianProfile->students()->pluck('students.id'); $studentQuery->orWhereIn('id', $guardianStudentIds); } // 场景3:当前用户是教职工,若同时兼任家长则追加关联子女数据,后续可在此扩展教职工管辖学生的查询规则 if ($currentUser->staffProfile) { if ($currentUser->staffProfile->staff_guardian_id) { $staffAsGuardianStudentIds = $currentUser->staffProfile->staff_guardian->students()->pluck('students.id'); $studentQuery->orWhereIn('id', $staffAsGuardianStudentIds); } } // 去重后获取结果,可根据需求替换为分页查询 $relatedStudents = $studentQuery->distinct()->get();
注意事项
- 现有多对多关联未显式指定中间表,Laravel会默认按模型名字母顺序拼接中间表名,如果业务中自定义了中间表名称,需要在
belongsToMany方法第二个参数传入中间表名,避免关联报错 - 查询时加
distinct()是为了避免同一学生因用户多重身份被重复返回,比如用户既是学生本人又是另一名学生的家长时,不会出现重复数据 - 后续如果新增教职工授课/管辖班级的关联逻辑,直接在教职工身份的判断分支中追加对应查询条件即可,不需要调整整体查询结构
内容的提问来源于stack exchange,提问作者Dewi
相关产品推荐
相关产品推荐

