Inheritance SINGLE_TABLE

a marqué ce sujet comme résolu.

Hello, Voila je cherche a créer un bundle de Tag.

Admettons que l'on ne sache pas le nombre et le nom des entités qui seront lié à cette entité Tag. C'est à dire qu'elle pourra être lié a une seule entité, comme à plusieurs entités.

Une personne m'a mise sur la piste. Alors j'ai créer une interface Taggable.

Puis une Class abstraite Tagging qui implements l'interface et qui est une InheritanceType en mode SINGLE_TABLE et un discriminatorColumn pour pouvoir distinguer courante l'entité lié. L'entité Tagging a comme champs: id, model_id, model, tagi_id.

Et donc les entités qui pourront avoir des Tag hérite de la classe abstraite Tagging.

-Le problème c'est que tous les champs des entités lié ce retrouve dans la classe Tagging.

Par exemple si j'ai une entité Post qui contient les champs name,slug,content qui hérite de Tagging alors tous les champs que je viens de citer vont se retrouvé dans la table Tagging en base de données. Ce qui n'est vraiment pas pratique :/

-Ensuite lorsque je veux récupérer les posts, doctrine ne va pas chercher dans la table post mais dans Tagging.

Si quelqu'un pouvait m'éclairer sur ces points ce serait sympa.

Merci d'avance :)

+0 -0

Je dirais qu'il ne sert simplement à rien de mapper la classe mère en tant qu'entité mais uniquement les filles afin qu'elles aient chacune leur table.

si le tag est commun à toutes les entités liées (tu peux trouver un post, un article, un tutoriel etc. selon un même tag) et du coup il suffit de créer une entité Tag et de la lier aux autres tables.

+0 -1

Salut artagis et merci pour ta réponse, mais je n'ai pas saisie ce que tu veut dire.

En faite je voudrais une entité intermédiaire qui puisse faire la relation entre les Tag et mes autres entitées.

Comme une relation MANYTOMANY un peu près à la différence que je voudrais une seule table pour la liaison et non pas par exemple une table pour Article et Tag, une autre pour Portfolio et Tag …

Dans l'entité de liaison (Tagging) qui est lié à mes autres entités il y aurait que les champs suivant:

  • id: classique
  • type: qui est le type de l'entité lié
  • model_id: qui est l'id de l'entité lié
  • tag_id: qui est l'id du tag.

j'ai bien ces champs dans ma table Tagging mais le problème c'est qui me rapatrie aussi tous les champs des entités lié aussi dans la table. C'est ce problème qui m'embête un peu.

Et bien admettons que mon entité Tag possède 3 tags en bdd. Je voudrais que 20 autres entités de mon applications soit lié à l'entité Tag pour pouvoir attribué ces tags en bdd à mes 20 autres entités.

Je ne vais pas faire un manytomany car cela me créera 20 table de liaison en bdd.

Le truc c'est qu'il faudrait justement une table intermédiaire pour lier ces 20 entités à la table Tag.

Ou bien peut-être est-ce que je fais fausse route, et que tu à une meilleur autre soluce à me proposer :)

Edit:

Je viens de lire la première réponse que tu a edité, mais la soluce proposé n'est pas optimisé.

Cela voudrais dire que si je fais un MANYTOONE dans Tag vers chaque entité, j'aurais dans ma table Tag les champs:

  • article_id
  • tutoriel_id ....

Et cela voudrais dire que si j'insère un tag dans la table seulement pour article_id, tuoriel_id sera null.

Et si j'insère un tag seulement pour tutoriel_id, article_id sera null.

Ma table Tag aura des trous partout.

De plus je voudrais justement ne pas touché a la table de liaison car je ne suis pas censé savoir quel entité sera lié aux Tags.

+0 -0

Hello,

C'est ce qu'on appelle une relation Many-to-Any, et ce n'est pas géré par Doctrine. Pas besoin de faire de inheritance ou quoique ce soit… Il faut que tu fasses toi même une table de liaison TaggableObject (ou autre nom, au choix) qui sera liée à un Tag et à deux champs : un object id et un object class. Mais par la suite, il te faudra gérer toi-même les relations (tu n'aurais plus cette satanée magie de Doctrine)

En gros, il faut faire un truc qui s'approche de ceci : https://gist.github.com/Taluu/2b07700c99edcd8ef8aa

Le but étant ici aue chaque objet pouvant être "taggé" implémente l'interface TaggableInterface (le travail est maché si tu inclus le trait TagTrait.... Mais encore une fois, il te faut gérer toi-même la gestion de la relation des objets. Je ne le fais pas ici, sinon ce serait te macher tout le travail…

+1 -0

Hello Talus et merci pour ta réponse.

Ha ok c'est un peu l'idée de base que j'avais au niveau de l'interface et tout ça, sauf que je n'avait pas pensé à devoir tous gérer à la main au niveau des liaisons.

Dommage que doctrine n'implémente pas ce genre de liaison^^.

Je voulais justement que l'on me mette seulement sur la piste et pas la soluce toute faite. Tu as bien fait.

Encore merci et Bonne journée ^^

Salut !

Je suis peut-être à côté de la plaque, mais j'ai relevé le fait que tu ne souhaitais pas avoir les champs de toutes les entités enfant dans la même table que celle où se trouvent les valeurs propres à Tagging.

Or, outre le système d'héritage avec table unique, il y a aussi celui avec tables jointes (remplacer SINGLE par JOINED, si je ne me trompe). Les champs de Tagging seraient dans leur table, les champs de tes entités enfant dans les leurs, avec juste un champ supplémentaire pour contenir l'ID de la table de l'entité mère. Alors certes, cela ne change en rien le fait que l'on multiplie les tables de liaison entre les entités "taggables" et l'entité Tagging ou ses enfants, mais c'est supporté par Doctrine, si ça peut aider.

La solution de Talus a ceci de compliqué pour moi que je ne vois pas comment opérer d'autre qu'en deux temps pour récupérer toutes les entités liées au même tag qu'une d'entre elles en particulier (si c'est le but final) :

  1. récupérer le tag et ses noms d'entités liées
  2. récupérer les entités liées en fonction de ces noms
+0 -0

une union?

artragis

Si tu le dis  :p
Je ne connais pas assez. Le peu que j'en sais, c'est que ça risque d'être gourmand, non ?

Sinon, voilà ce dont je me souvenais du cookbook, mais c'est pas vraiment le besoin (je n'avais retenu que le nom évocateur de ResolveEntityListener).

+0 -0

Salut !

Je suis peut-être à côté de la plaque, mais j'ai relevé le fait que tu ne souhaitais pas avoir les champs de toutes les entités enfant dans la même table que celle où se trouvent les valeurs propres à Tagging.

Or, outre le système d'héritage avec table unique, il y a aussi celui avec tables jointes (remplacer SINGLE par JOINED, si je ne me trompe). Les champs de Tagging seraient dans leur table, les champs de tes entités enfant dans les leurs, avec juste un champ supplémentaire pour contenir l'ID de la table de l'entité mère. Alors certes, cela ne change en rien le fait que l'on multiplie les tables de liaison entre les entités "taggables" et l'entité Tagging ou ses enfants, mais c'est supporté par Doctrine, si ça peut aider.

La solution de Talus a ceci de compliqué pour moi que je ne vois pas comment opérer d'autre qu'en deux temps pour récupérer toutes les entités liées au même tag qu'une d'entre elles en particulier (si c'est le but final) :

  1. récupérer le tag et ses noms d'entités liées
  2. récupérer les entités liées en fonction de ces noms

Ymox

Le problème avec cette solution (celle de la joined inheritance) est que tu te retrouves avec plusieurs entités (une par relation). Ce qui n'est pas une solution valable…

Oui, la solution que je donne demande souvent de récupérer ses entités en deux temps (un premier temps pour choper les id / class des objets concernés par les tags demandés, puis un deuxieme temps (en x requetes, ou une union mais c'est chiant à gérer, et peu pratique, car ca demande du sql natif) choper les entités en fonction de leur id / class. Mais c'est la plus pratique et la moins gourmande.

Celle que tu proposes, comme je l'ai dit, demande à maintenir plusieurs entités, et demande tout autant de requetes (si ce n'est plus, ou des plus complexes tout du moins…) pour choper les dites entités. Si tu ne chopes jamais les entités via un id de tag, mais que plutot depuis un objet tu veux choper les tags correspondants, à la rigueur, ca peut le faire via une single, mais ca suit toujorus plus ou moins le même schéma. Mais cette solution demande de jouer un peu avec le schema tool de Doctrine, et c'est assez complexe à réaliser. Et ce n'est pas le cadre de ce qu'il cherche à faire ici de toutes manières :)

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte