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

miigaa's avatar
Level 24

Make a BelongsToMany Relation with Third Model?

How Can i make this relation? I have tables like below

students
    id
batches
    id
enrollments
    student_id
    batch_id
fees
    id
    batch_id

batches and students are have a belongsToMany relation ship. Now i want to make a relation fees with students? How can i make it? I've tested below but it doesn't work

public function students()
{
    return $this->belongsToMany(Student::class, 'enrollments', 'batch_id', 'student_id');
}

it's running this query.

select *, (select count(*) from `students` inner join `enrollments` on `students`.`id` = `enrollments`.`student_id` where `enrollments`.`batch_id` = `fees`.`id` and `confirmed_at` is not null) as `students_count` from `fees` limit 1

select `students`.*, `enrollments`.`batch_id` as `pivot_batch_id`, `enrollments`.`student_id` as `pivot_student_id` from `students` inner join `enrollments` on `students`.`id` = `enrollments`.`student_id` where `enrollments`.`batch_id` = '1' and `confirmed_at` is not null

as i see enrollments.batch_id matches with fees.id. It should matches with fees.batch_id as i expect.

Is it possible? or am i doing wrong? Thanks

0 likes
4 replies
Hesto's avatar

@selmonal You know what? The easiest way is to pull that package: https://github.com/laracasts/Laravel-5-Generators-Extended

Install it and delete enrollments table. Then run artisan command to create this table again, but with Laravel's convention :

php artisan make:migration:pivot batches students

and then

php artisan migrate

In your Students model use that method

public function batches()
{
    return $this->belongsToMany(App\Batch::class);
}

In your Batch model use:

public function students()
{
    return $this->belongsToMany(App\Student::class);
}

Just follow conventions and you will never have to think why smth doesn't work.

miigaa's avatar
Level 24

I don't agree with you @Hesto. I already followed that convention If you see the relation of batches and students.

Adding third model like Fee it's very convenient to me. It'll allow me I can eager load, use withCount('students') and other stuffs.

Hesto's avatar

@selmonal So add it. It should belongs to Batch right?

so in Batch model add

public function fees()
{
    return $this->hasMany(App\Fee::class);
}

and in Fee model add

public function batch()
{
    return $this->belongsTo(App\Batch::class);
}
miigaa's avatar
Level 24

@hesto I just want to fetch who should pay this fee? I know there is a that relation. I don't want to access students through a batch

The relation that i'm saying can do below!

$fees = Fee::latest()->withCount('students')->get(); // Very convenient, isn't it?

Please or to participate in this conversation.