问题
I'm stuck with a problem where I have to sort / order a collection of models by their relationship's data.
I've got it setup like this:
Models:
User
, Team
, TeamUser
, Role
The TeamUser
model is a pivot model / table (containing user_id
and team_id
.
If it's worth mentioning I am also using spatie/laravel-permissions for the roles.
How would I go forth when I want to sort the users in a team by their role.name
?
I'm talking about the users()
relation in the Team
model (see further down for code sample).
Some users have the role team-leader
and most have the role team-seller
. I've tried doing a ordinary ..->sortBy('role.name')
but that doesn't seem to work. Thanks in advance if anyone could help me out.
User.php
/**
* Team relation
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function team()
{
return $this->belongsToMany('App\Team', 'team_users', 'user_id', 'team_id');
}
Team.php
/**
* User relation
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function users()
{
return $this->belongsToMany('App\User', 'team_users', 'team_id', 'user_id')->withTimestamps();
}
回答1:
if you want to order the result based on nested relation column, you must use a chain of joins:
$values = Team::query()
->leftJoin('users', 'users.team_id', '=', 'teams.id')
->leftJoin('model_has_roles', function ($join) {
$join->on('model_has_roles.model_id', '=', 'users.id')
->where('model_has_roles.model_type', '=', 'app\Models\User');
})
->leftJoin('roles', 'roles.id', '=', 'model_has_roles.role_id')
->orderBy('roles.name')
->get();
i have tried it, it work just fine.
please note that if you want to order by multiple columns you could add 'orderBy' clause as much as you want:
->orderBy('roles.name', 'DESC')->orderby('teams.name', 'ASC') //... ext
来源:https://stackoverflow.com/questions/61190637/laravel-eloquent-sort-by-role-name-on-relationship-model