Bonjour a tous, j'ai une question de fond relative à SQL / Doctrine / Symfony. Je manque un peu d'expérience sur le sujet et j'ai besoin de votre expertise.

Pour faire simple disons que j'ai deux entités : User et Team.

  • Un User peut s'inscrire dans une Team pour en faire partie -> relation ManyToMany que je nommerai Member.
  • Une Team peut avoir une visibilité restreinte a certains Users leur permettant de la rejoindre -> relation ManyToMany que je nommerai Viewer.

Je me retrouve donc avec deux tables pivots. A coup d'extensions Doctrine je filtre mes résultats avec le QueryBuilder et le tour est joué.

Mais voilà… j'hésite… je doute… j'ai l'impression qu'il me manque un truc.

J'aurais pu aussi créer une entité intermédiaire, disons UserTeam, dans laquelle j'aurai géré ma visibilité ET ma notion de membres. Mais j'ai l'impression de perdre en lisibilité dans ce cas.

Qu'auriez-vous fait dans cette situation ?
Y a-t-il des points contraignants à faire cohabiter ces deux relations ManyToMany entre les deux mêmes entités ?
Qu'en est-il si je passais à 3 relations ManyToMany ? 4 relations ?

Bonus : J'ai pendant un moment pensé à stocker ma visibilité directement dans Team sous forme de Array d'ID utilisateurs. Mais dans ce cas il me devient difficile d'appeler la liste des Teams visible par un User spécifique. Un avis là-dessus ?

Merci pour vos bons conseils !

7 réponses


Grafikart
Réponse acceptée

Il faut voir au niveau de la gestion, si tu peux supprimer un viewer qui est déjà membre d'une équipe dans ce cas là ça peut être intéréssant de n'avoir qu'une table de liaison avec un champ "isMember". Sinon 2 tables pour une gestion séparé des viewer / member.

Fernand tatchum
Réponse acceptée

Ou alors tu peux tjrs avoir une seule table pivot UserTeam avec les ids de User et Team et un champ supplémentaire is_member qui sera un booléen. Alors de création d'une Team tu sélectionnes les User et tu fais appel à la relation UserTeam pour créer un enregistrement . Lorsqu'un User s'enregistre en tant que member d'une Team tu défini juste le champ is_member à True.

Negwael
Auteur
Réponse acceptée

Merci pour vos retours. Ce que j'ai pu comprendre c'est que la solution idéale est celle qui s'adapte à la logique métier.
Dans mon cas, mes membres ayant obligatoirement ma notion de visibilité, je suis parti sur une seule table de jointure UserTeam sur laquelle j'ai appliqué un workflow dont le premier état est Viewer, et le second est Membre. Cela me laissera plus de possibilité pour gérer l'état de mes membres à l'avenir, avec potentiellement plusieurs état de membres (validé, en attente de validation, ...)
Bonne continuation à tous.

Bonsoir Negwael,
Je ne saisi pas très bien le deuxième point où tu parles de visibilité restreinte. Je ne sais pas si tu essaies de dire que certains Users ne peuvent pas voir une Team en particulier ou autre chose. Peut-tu être plus clair stp ?

Negwael
Auteur

C'est bien ça. Quand je parle de visibilité sur une Team : l'administrateur createur de l'equipe peut specifier une liste de User qui a le droit de consulter la Team en question et d'en devenir Member.
Le User qui affiche /teams ne peut consulter que les Team pour lesquels il est Viewer.

Bonjour,

Il faut être très vigilant sur les relations qui pointent entre les deux mêmes entités car on peut vite se retrouver avec des erreurs de référence circulaire.
Perso j'utiliserais la solution de la table pivot, et tu peux facilement utiliser ton entité UserTeam pour gérer le type de relation entre les users et les teams, et l'affichage en est facilité.
De plus ton bonus est géré avec un simple $user->getTeams().

Bonjour Negwael,
Là je comprend mieux. Dans ce cas je pense que tu auras alors deux rélations ManyToMany liant les entités User et Team, la première sera Member pour attacher un User à une Team et la seconde Viewer pour spécifier quel User peut voir quelle Team. Il n'y aura pas une liaison direct entre ces pivots, lors de la création d'une Team tu sélectionnera juste les User capable de la voir en faisant appel à la relation Viewer, ainsi un User ne pourra voir que les Team dont il est capable de voir et s'enregistrer en tant que membre de ces Team via la relation Member.