Search code examples
phplaraveleloquenteloquent-relationship

Sort by relationship first in laravel


I have two tables: admins and log_doctor_infos. admins table has relationship hasOne with log_doctor_infos throught doctor_id like this.

In model Admin:

public function logDoctorInfo() {
    return $this->hasOne(LogDoctorInfo::class, 'doctor_id', 'id');
    // Model LogDoctorInfo is log_doctor_infos table
}

And in Model LogDoctorInfo:

public function doctor(){
    return $this->belongsTo(Admin::class, 'doctor_id', 'id');
    // Model Admin is admins table
}

I get all data form admins table and i want to sort record has relationship with log_doctor_infos to top.

Yellow record, which has relationship with log_doctor_infos and i want to sort it in top.

Edit: i use paginate in this query and i really want to get quantity of Yellow record.

Thanks for reading!

Example

In my controller, i have custom filter and paginate. Help me.

public function index(Request $request) {
    $fullname = $request->query('fullname', NULL);
    $phone = $request->query('phone', NULL);
    $status = $request->query('status', NULL);

    $doctors = (new Doctor)->newQuery();
    if ($fullname != NULL) {
        $doctors = $doctors->where('fullname', 'LIKE', '%'.$fullname.'%');
    }
    if ($phone != NULL) {
        $doctors = $doctors->where('phone', 'LIKE', '%'.$phone.'%');
    }
    if ($status != NULL) {
        $doctors = $doctors->where('status', $status);
    }
    $doctors = $doctors
    // ->with(array('logDoctorInfo' => function($query) {
    //     $query->orderBy('updated_at', 'ASC');
    // }))
    ->latest()
    ->paginate()
    ->appends([
        'fullname' => $fullname,
        'phone' => $phone,
        'status' => $status
    ]);
    // dd($doctors);
    return view('admin.doctors.index', compact('doctors'));
}

Solution

  • you can use the withCount method.

    Admin::withCount('logDoctorInfo')
           ->orderBy('log_doctor_info_count', 'desc')
           ->paginate(5);
    

    Your controller will look like this

    public function index(Request $request) {
        $fullname = $request->input('fullname', NULL);
        $phone = $request->input('phone', NULL);
        $status = $request->input('status', NULL);
    
        $doctorQuery = Doctor::query();
        if ($fullname) {
            $doctorQuery->where('fullname', 'LIKE', '%'.$fullname.'%');
        }
        if ($phone) {
            $doctorQuery->where('phone', 'LIKE', '%'.$phone.'%');
        }
        if ($status) {
            $doctorQuery->where('status', $status);
        }
        $doctorQuery->withCount('logDoctorInfo')
            ->orderBy('log_doctor_info_count');
    
        $doctors = $doctorQuery->paginate()
            ->appends([
                'fullname' => $fullname,
                'phone' => $phone,
                'status' => $status
            ]);
        // dd($doctors);
        return view('admin.doctors.index', compact('doctors'));
    }