DEV Community

Michael Messerli
Michael Messerli

Posted on

Custom order with sortBy() -- Bonus Livewire implementation

I recently ran into an issue where I wanted to order a list of users by their role. The problem is the roles don't have any kind of order built in, and they're not alphabetical.

Problem

Teams have a many-to-many relationship with Users. On the pivot table we have a role attribute.

Users can be one of 4 roles within a Team: Owner, Admin, Moderator, or Member.

We want to list members of a team in the above order.

Solution

In the ->sortBy() return a Closure with the array of keys you'd like to order by, and return their index.

return $this->team->users()->withPivot('role')->get()->sortBy(function ($item, $key) {
    $order = ['owner', 'admin', 'moderator', 'member'];
    return array_search($item['pivot']['role'], $order);
})
Enter fullscreen mode Exit fullscreen mode

Bonus: Building this list in Livewire

Changing user roles

// livewire/Teamwork/MemberList.php
class MemberList extends Component
{
    public $team;

    protected $listeners = [
        'membersUpdated' => 'updateList',
        'roleUpdated' => 'updateList'
    ];

    public function mount($team)
    {
        $this->team = $team;
    }

    public function updateList()
    {
        //
    }

    public function render()
    {
        return view('livewire.teamwork.member-list', [
            'members' => $this->team->users()->get()->sortBy(function ($item, $key) {
                $order = ['owner', 'admin', 'moderator', 'member'];
                return array_search($item['pivot']['role'], $order);
            })
        ]);
    }
}
Enter fullscreen mode Exit fullscreen mode

Wrapping Up

So this works great for me and I was happy to find a way to create a custom order. I'd like to hear from someone with more experience about alternate ways to accomplish this.

Top comments (0)