Inner join many to many avec symfony et doctrine
Récupération des managers
Vous avez par exemple deux entités User et Role. Ces deux entité sont liées par une relation de ManyToMany c’est à dire qu’un utilisateur a un ou plusieurs rôles et qu’un rôle a un ou plusieurs utilisateurs.
Niveau base de données, doctrine crée une table intermédiaire comportant les (user_id et role_id) qui permet de faire la relation.
Cependant, en Symfony nous ne parlons qu’en entité. Pour récupérer tout les utilisateurs du rôle ROLE_RESPONSABLE
, il faut faire un code DQL de ce genre :
- Dans
/src/repository/UserRepository
.
/**
* @return Appel[] Returns an array of Appel objects
*/
public function getManagers()
{
return $this->createQueryBuilder('u')
->innerJoin('u.userRoles', 'r')
->andwhere('r.title LIKE :title')
->setParameter('title', 'ROLE_RESPONSABLE')
->getQuery()
->getResult();
}
- Dans le controlleur :
/src/controller/UserController
use App\Repository\UserRepository
...
/**
* @Route("/blabla")
*/
class BlablaController extends AbstractController
{
public function new(UserRepository $userRepository)
{
$manager = $userRepository->getManagers(),
...
}
}
Symfony, c’est vraiment se compliquer la vie pour rien. Pour rappel ce genre de chose se fait VRAIMENT TRÈS TRÈS SIMPLEMENT EN SQL classique. (C’est juste pour ceux qui on oublié ce qu’est le développement à la base.)
SELECT user.username, user.email
FROM user, user_role, role
WHERE user_role.user_id = user.id
AND user_role.role_id = role.id
AND role.title = "ROLE_RESPONSABLE"
ORDER BY user.username
Ajout de la liste dans le formulaire
Si vous voulez par exemple afficher un <select>
qui contient la liste des utilisateurs portant le rôle de responsable. Vous devez modifier votre formbuilder :
- Appel du formbuilder
$form = $this->createForm(
AppelType::class,
$appel,
[
'managers' => $userRepository->getManagers(),
]
);
- Ajout d’option (par défaut) au formbuilder
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'managers' => [],
]);
}
- Application des options au champs
->add('responsable', EntityType::class, [
'class' => User::class,
'choice_label' => 'fullname',
'label' => 'Nom du Responsable',
'choices' => $options['managers'],
])
Voilà…. C’est long et chiant. Sans ce genre de framework ça se fait en 3 sec.