How to SortBy in relationship hasMany?

What seems to be the problem:
I can’t sortBy Roles in users table

Steps to Reproduce:

Are you using the latest version of Livewire: yes

Do you have any screenshots or code examples:
user-table.blade.php

<th class='border px-2 py-1'>
<a wire:click.prevent="sortBy('user->roles')" role="button" href="">

  Roles  @include('partials._sort-icon', ['field' => 'role'])

</a></th>

userTable.php

<?php

namespace App\Http\Livewire;

use App\Models\User;

use Livewire\Component;

use Livewire\WithPagination;

use Illuminate\Foundation\Auth\Access\AuthorizesRequests;

class UsersTable extends Component

{

    use WithPagination;

    use AuthorizesRequests;

    

    public $search;    

    public $perPage ;

    public $sortField ;

    public $sortDirection ;

    public function mount()

    {

        $this->perPage = 5;

        $this->search="";

        $this->sortField = 'username';

        $this->sortdirection =true;

    }

    public function sortBy($field){

        if($this->sortField === $field){

            $this->sortDirection = !$this->sortDirection;

        }else{

            $this->sortDirection = true;

        }

        $this->sortField = $field;

    }

    public function render()

    {

        if ($this->search != ""){

            return view('livewire.users-table', [

                'users' => User::where('username', 'LIKE', '%' . $this->search . '%')

                        ->orWhere('firstname', 'LIKE', '%' . $this->search . '%')

                        ->orWhere('lastname', 'LIKE', '%' . $this->search . '%')

                        ->orwhereHas('roles', function ($query)  {

                                     $query->where('name', 'LIKE', '%' . $this->search . '%')

                                     ->orderBy($this->sortField, $this->sortDirection ? 'asc':'desc');

                                }

                        )->orderBy($this->sortField, $this->sortDirection ? 'asc':'desc')->paginate($this->perPage),    

            ]);

        }else {

            return view('livewire.users-table', [

                'users' => User::with('roles')

                        ->orderBy($this->sortField, $this->sortDirection ? 'asc':'desc')

                        ->paginate($this->perPage),    

            ]);

        }

    }

}

Hi @nouart

I would recommend you watch this video from Jonathan Reinink:

https://vimeo.com/showcase/7060635/video/394206831#t=2860s

The whole video is very good on how to reduce database queries and Eloquent memory usage in Laravel

1 Like

Hi @ashleyhood
Any one can help, no solution at this time !!!

Your problem is here: ->orwhereHas('roles', function ($query) {
First, it’s orWhereHas().
Second, closures are in their own namespace in php, so they don’t have access to $this->search, $this->sortField, or $this->sortDirection. You have to pass them into the closure with use().