J'ai 2 tables
-Users : id, nom
-Roles: id, nom
Ces deux tables ont une relation many to many avec la table pivot
-Role_user : role_id, user_id
Comment puis-je regrouper tous les utilisateurs par nom de rôle ?
J'ai essayé ceci
User::with('roles')->get()->groupBy('roles.name') ;
mais il semble que cela ne fonctionne que pour les relations de type "un à plusieurs".
Re j'ai trouvé la solution en faisant
User::with('roles')->get()->groupBy('roles.*.name');
Salut, il faut que tu penses dans l'autre sens
// Récupère les rôles avec les utilisateurs associés
$roles = Role::with(['users'])->get();
// Exemple qui affiche tous les utilisateurs de chaque rôle
$roles->each(static fn(Role $role) => dump($role->users));
Est-ce que ça pourait regrouper les utilisateurs comme ça :
Illuminate\Database\Eloquent\Collection {#290 ▼
#items: array:2 [▼
"ADMIN" => Illuminate\Database\Eloquent\Collection {#293 ▶}
"USER" => Illuminate\Database\Eloquent\Collection {#291 ▶}
]
#escapeWhenCastingToString: false
}
ou dans la collection "ADMIN" j'ai tous les utilisateurs qui sont admin et dans "USER" les utilisateurs qui sont de simple utilisateur
Oui, c'est possible en faisant
$roles = Role::with(['users'])->get()->pluck('users', 'name'); // A la place de `name`, mettre la colonne SQL qui contient le nom du rôle
Ça marche mais cette maniere de faire ne va pas m'aider pour la suite car j'aurais besoin d'utiliser les relations qui appartienne au model user pour faire de requete dessus. Donc y'aurais pas un moyen de partir du sens de User ?
Parce-que de base voila à quoi ressemble ma requete
User::with(['roles', 'attribution'])
->whereHas('attribution', function ($query) {
$query->whereMonth('date_attribution', $this->month);
})
->get()
->groupBy('roles.name');
Est-il possible de faire ca dans le sens inverse ?
J'ai pas testé, mais quelque chose du genre devrait sûrement fonctionner. Deplus, si tu es sur les dernières versions de Laravel, tu peux remplacer ton whereHas
par un whereRelation
comme j'ai mis dans l'exemple.
User::with(['roles', 'attribution'])
->whereRelation('attribution', 'data_attribution', $this->month)
->get()
->reduce(static function (Collection $agg, User $user) {
$user->roles->each(static function (Role $role) use (&$agg, $user) {
$agg[$role->name][] = $user;
});
return $agg;
}, collect());
J'ai remplace ce bout de code
$agg[$role->name][] = $user;
par ca
$agg[$role->name] = $user;
Et ca l'air de fonctionner sauf que pour chaque role il y'a qu'un seul utilisateur
$agg = collect();
$agg->put($role->name, [...$agg->get($role->name, []), $user]);
A la place de
$agg[$role->name][] = $user
Là ca fait que prendre le role associe au premier utilisateur c'etait mieux avec ca
$agg[$role->name] = $user
J'ai testé avec ta methode
$roles = Role::with(['users.attribution'])->get()->pluck('users', 'name')
Et c'est bien ce que je veux mais y'a tous les roles qui sont listés alors que moi je voudrais seulement les roles qui appartiennent au moins à un utilisateurs. Comment porrais-je faire ça ? Merci d'avance
Salut,
Pour avoir que les rôles qui ont des utilisateurs, tu peux ajouter ->filter(static fn(Role $role) => $role->users->isNotEmpty()
qui va garder que les rôles qui ont des utiisateurs liés
User::with(['roles', 'attribution'])
->whereRelation('attribution', 'data_attribution', $this->month)
->get()
->filter(static fn(Role $role) => $role->users->isNotEmpty()) // Filtre les rôles avec des utilisateurs
->reduce(static function (Collection $agg, User $user) {
$user->roles->each(static function (Role $role) use (&$agg, $user) {
$agg[$role->name][] = $user;
});
return $agg;
}, collect());