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

sirbobz's avatar

Group by eloquent BelongsTo relationship

I have two models: Student and StudentArchive as below:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;


class Student extends Model
{

    protected $fillable = ['school_id', 'first_name', 'second_name', 'admin_number', 'archival_status'];

    public function student_archives(): HasMany
    {
        return $this->hasMany(StudentArchive::class);
    }
}

StudentArchive:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class StudentArchive extends Model{

    protected $casts = ['student_id' => 'int'];

    protected $fillable = ['student_id', 'class_of'];

    public function student(): BelongsTo{
        
        return $this->belongsTo(Student::class);
    }
}

I have the Student Model with the student details. Once a student graduates, I add their student_id to the StudentArchive model and the year of graduation.

I would want to get the count of students in the StudentArchive model per year.

I have tried as below but the count is wrong, it gets one count for all. Anyone?

 StudentArchive::withCount(['student' => function($query) {
        return $query->where('school_id', Auth::user()->school_id)
        ->where('archival_status', true);  }])
        ->groupBy('class_of')
        ->get();
0 likes
1 reply
sirbobz's avatar

I have found a way

StudentArchive::whereHas(['student' => function ($q) { $q->where('school_id', Auth::user()->school_id)->where('archival_status', true); }])->select('class_of', DB::raw('count(*) as count_students'))->groupBy('class_of')->get()

Please or to participate in this conversation.