Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

MahmoudAdelAli's avatar

Access relation between 2 relations many to many

Hi , i have 4 tables

courses
students
teachers
course_student

courses has relation with students many to many throw course_student and i named this relation as subscription

#Courses Model
  public function subscriptions()
    {
        return $this->belongsToMany(Student::class,'course_student','course_id');

    }

and teacher has relation with courses throw teacher_id column that inside the courses table

#Teacher Model
    public function courses() {
        return $this->hasMany(Course::class);
    }

Now i want to get all students for each teacher at his dashboard so i try with

    public function students(): HasManyThrough
    {
        return $this->hasManyThrough(Student::class, Course::class, 'teacher_id', 'id');
    }

and there's wrong data i collect from this relation , so i decided to make at as regular method like

 public function students(): \Illuminate\Support\Collection
    {
        return collect($this->courses)->flatMap(function ($course){
            return collect($course->subscriptions);
        })->unique('id');
    }
/**
flatmap to get all students at one collection cause regular map 'll create a collection for each course and each collection 'll has all students inside , and unique to filter all students and get the unique cause may the student has subscription at 2 or 3 courses for same teacher , 
*/

and now everything work correctly , but idk if this a laravel way or best practice or even clean code , so any recommendation ?

0 likes
6 replies
tisuchi's avatar

@mahmoudadelali I believe you can do that also:

Teacher.php model:

public function students()
{
    return $this->belongsToMany(
        Student::class,
        'course_student', // Intermediate table
        'course_id', // Foreign key on course_student table...
        'student_id', // ...linking to students table
        'id', // Local key on teachers table...
        'teacher_id'  // ...linking to course table
    )->distinct();
}
3 likes
Snapey's avatar

Now i want to get all students for each teacher at his dashboard

all students irrespective of what course?

3 likes
PovilasKorop's avatar
Level 11

Yes, from what I know, in Laravel, there's no way to define a hasManyThrough relationship between hasMany and belongsToMany.

The closest to that is a package hasManyDeep, but in its docs, I found only ManyToMany → HasMany, not the other way around HasMany → ManyToMany like in your case.

So your code is ok, apart from the fact that you don't need the collect() in the beginning:

 public function students(): \Illuminate\Support\Collection
    {
        return $this->courses->flatMap(function ($course){
            return collect($course->subscriptions);
        })->unique('id');
    }
2 likes
thephilosoft's avatar

Why not use simple SQL?

return collect(Student::hydrate(DB::query('usual SQL query here')));

Please or to participate in this conversation.