Bonjour à tous,
Je planche actuellement sur un projet et je suis devant un choix à faire concernant l'un de mes models, sauf que je sèche. N'ayant pas trouvé de retour d'expérience sur ce sujet, je me tourne vers vous.
Le problème est le suivant :
- Nous avons un modèle club qui a une ou plusieurs équipes.
- Lorsque le club est créé, une équipe "par défaut" est créé, puisqu'un club possède forcément une équipe au minimum.
- Il n'y a pas de limite maximale au nombre d'équipes.
- Par défaut un club comporte des éléments (blason, nom, adresse, etc) et les équipes en possèdent d'autres (division, effectif, sponsor, etc)
Face à cette situation, nous sommes donc partis sur un model Club hasMany Team, tout simplement, où le club possède les champs propres au club et les team possèdent le reste.
Le souci qui se pose, c'est que la plupart des champs d'une équipe sont redondants. Généralement toutes les équipes du club possèdent le même sponsor, l'effectif de chaque équipe est le même sauf celui de la dernière, et ainsi de suite.
Niveau back-office, il était fastidieux pour les propriétaires du club d'ajouter à chaque fois la même information pour chacune des équipes ; et également dans le cas de mise à jour, un changement de sponsor par exemple, il était ennuyeux de devoir mettre à jour chaque équipe.
Pour pallier à ça, nous avons donc mis en place un système d'héritage :
- Tous les champs de l'équipe 1 doivent forcément être renseignés
- A partir de l'équipe 2, les champs vides héritent des propriétés de l'équipe précédente, donc la 2 hérite de la 1, la 3 de la 2, etc...
Mais cela nous pose actuellement des difficultés et pas mal de questions puisque :
- soit on enregistre les valeurs de l'héritage au moment de la création ou de la mise à jour : dans ce cas de figure, on stocke beaucoup de données identiques en BDD, et dans le cas d'une mise à jour d'une équipe, ça complique la chose puisqu'on ne pourra pas update les équipes qui partage les mêmes propriétés celles-ci ayant alors un sponsors différent, par exemple. A oublier donc.
- soit on fait les choses "à plat", et quand on récupère l'équipe 7, si elle a des champs vide on récupère également la 6 pour avoir les bonnes données. Le souci c'est que dans la plupart des cas, on se retrouve quand on récupère une équipe à récupérer finalement les propriétés de toutes celles qu'il y a avant. Aujourd'hui c'est ce qu'on a en place, mais c'est gourmand et pas optimal du tout.
Du coup, nous avons réfléchi aux pistes suivantes :
- soit on fait des HABTM dans tous les sens, pour les sponsors, pour les effectifs, et pour plus ou moins tout, en liant les à l'équipe et aux équipes inférieures sauf si une liaison est déjà établie dans les équipes inférieures. Ca demande pas mal de travail dans le beforeSave() mais ça devrait pouvoir se faire.
- soit on gère ça avec une seule table "scallable". Je m'explique : on a le club et on lui ajoute un champ "équipes", administrable en back-office qui permet de spécifier le nombre d'équipe (et d'en ajouter via un bouton qui incrémente la valeur, par exemple). Tous les champs qui composent actuellement le model Team passent dans le model Club, et dedans on va stocker des objets/tableaux JSON contenant les données sous forme d'héritage.
Je ne sais pas si je me fais bien comprendre, mais par exemple dans le cas d'un club qui a 6 équipes, les effectifs pourraient ressembler à ça :
{
"effectif":
{
"1":"23",
"2":"",
"3":"",
"4":"14",
"5":"",
"6":""
}
]
}
L'avantage c'est que l'on conserve la logique d'héritage et que l'on stocke tout dans un seul modèle. Fini les find qui vont appeler 6 équipes pour être certains d'avoir toutes les données de la sixième.
Autre avantage, c'est que c'est modulaire. On peut ajouter un champ à la volée, ce qui créera un champ avec une classe similaire (effectif en théorie), et un id différent (effectif-7). Ensuite au parsing, on a simplement prendre les valeurs des différents champs pour les remettre dans un objet JSON et hop, c'est bon pour l'update.
C'est une idée simplement, mais elle me semble plus simple et demande moins de dev que des HABTM pour chacun des champs, avec les tables de liaison que ça implique, les règles de vérification dans le beforeSave, etc.
Après, c'est peut être pas top point de optimisation, et effectivement, on récupère les données des autres équipes quand on veut en afficher une, mais ceci dans une seule requête. Et je pense que l'un dans l'autre, stocker un JSON compressé dans un champ text demande certainement moins de ressources qu'une dizaine de tables de liaison.
Voila, j'espère avoir des conseils sur la question.
Merci d'avance ;)