IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

Schema.yml relation récursive


Sujet :

Symfony PHP

  1. #1
    Membre habitué
    Ingénieur d'études et de développement
    Inscrit en
    Juin 2009
    Messages
    112
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur d'études et de développement
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2009
    Messages : 112
    Points : 154
    Points
    154
    Par défaut Schema.yml relation récursive
    Bonjour à tous.

    Je bosse sous symfony et je suis en train de créer mon model.
    Pour ce faire j'ai modéliser ma base de données sous MySQLWorkBench et j'ai exporté le SQL dans MySQL.

    Avec doctrine j'ai généré le schéma
    puis j'ai créé des fichier de fixtures pour peupler ma base.

    lorsque je charge les données
    j'obtiens une erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Couldn't call Doctrine_Core::set(), second argument should be an instance of Doctrine_Collection when setting one-to-m ny references.
    Je sais maintenant que cela vient du fait que j'ai une table pointant récursivement vers elle même : une catégorie peut contenir une catégorie, et doctrine attend un ordre spécial dans Schema.yml

    Savez-vous comment régler ce problème.

    Voici l'extrait de schema.yml et de mon fichier de fixture

    Schema.yml

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Category:
      connection: doctrine
      tableName: category
      columns:
        id:
          type: integer(4)
          fixed: false
          unsigned: false
          primary: true
          autoincrement: true
    .....
    .....
    relations:
        Category:
          local: id
          foreign: category_id
          type: many

    Fixture.yml


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    cobRel1:
        name: 1.0
        lvl: 3
        Category: cobEngi

    Merci d'avance.
    Dam

  2. #2
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    A priori ton schema est faux.

    Pour une relation réflective tu devrais avoir deux tables en fait.

    Vu qu'une catégorie peut avoir plusieurs sous catégories et qu'une sous catégorie peut avoir plusieurs catégories...

    Plus d'information sur ces relations particulières dans la documentation de Doctrine ici.

    Pour aller plus loin, il faudrait plus d'information sur la table catégorie et sur la liaison (tu fais notamment référence à un champ category_id qui n'existe pas).
    Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).

    • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
    • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
    • Une discussion est terminée ? Alors le bouton est votre ami !

  3. #3
    Membre habitué
    Ingénieur d'études et de développement
    Inscrit en
    Juin 2009
    Messages
    112
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur d'études et de développement
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2009
    Messages : 112
    Points : 154
    Points
    154
    Par défaut
    Si, le champs category_id existe, j'ai omis toute la déclaration de catégorie.
    La voici en entier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    Category:
      connection: doctrine
      tableName: category
      columns:
        id:
          type: integer(4)
          fixed: false
          unsigned: false
          primary: true
          autoincrement: true
        name:
          type: string()
          fixed: false
          unsigned: false
          primary: false
          notnull: true
          autoincrement: false
        description:
          type: string()
          fixed: false
          unsigned: false
          primary: false
          notnull: false
          autoincrement: false
        lvl:
          type: string(1)
          fixed: false
          unsigned: false
          primary: false
          notnull: true
          autoincrement: false
        category_id:
          type: integer(4)
          fixed: false
          unsigned: false
          primary: false
          notnull: false
          autoincrement: false
      relations:
        Category:
          local: id
          foreign: category_id
          type: many
        Item:
          local: id
          foreign: category_id
          type: many
        Pcm:
          local: id
          foreign: category_id
          type: many
    Donc si je comprends bien la doc de doctrine je dois créer une table 'category_reference' qui contient l'id de la catégorie parente et l'id de la catégorie fille.
    Mais n'est ce pas le schéma d'une relation n à n? Or je veux une relation 0-n, une catégorie parente peut contenir plusieurs filles mais une catégorie peut ne pas être contenue par une parente.

    MysqlWorkBench ma simplement créer une clé parent_id quand j'ai cliqué deux fois sur la table catégorie avec le sélecteur 1-n.

    Je teste quand même ce que recommande Doctrine.

    Merci beaucoup, je vous tiens au courant

  4. #4
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    J'ai un peu joué avec ton schéma, sur la base, mais pourquoi cela ne marcherait pas ?

    Par contre, j'ai remis le schéma à ma sauce, virer tous ce qui ne sert à rien (les paramètres sont à false par défaut, il ne sert à rien de les remettre et cela clarifie la lecture.

    J'ai viré la définition de l'Id, doctrine la place seul, sauf qu'elle est du type bigint, soit integer dans le schéma et non plus integer(4)

    Reste le plaisir de la relation que je commenterais après le schéma
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    Category:
      columns:
        name:
          type: string()
          notnull: true
        description:
          type: string()
        lvl:
          type: string(1)
          notnull: true
        category_id:
          type: integer
      relations:                           
        CategoryParent:                    <---- 1
          local: category_id                 <---- 2
          class: Category                    <---- 3
          foreign: id                            <---- 4
          foreignAlias: CategoryEnfants     <----- 5
    L'utilisation des paramètres est un peu particulier.
    • 1. Le nom de la relation ne doit pas obligatoirement être le nom de la table à lier, mais surtout le nom que l'on veut voir apparaître dans les méthodes de l'objet category
    • 2. le lien local, ok, ils sont tous les deux locals, mais celui-là est du côté Enfants...
    • 3. le nom de la classe à utiliser pour l'autre côté de la relation, vu que CategoryParent n'existe pas.
    • 4. le champ a lier sur la table distante spécifiée dans "class"
    • 5. la méthode a utiliser pour retrouver les category depuis la table distante

    OK, c'est pas claire dans une relation réflective et ce n'est pas l'endroit rêve pour comprendre le fonctionnement des relations entre deux tables vu qu'ici il n'y en a qu'une.

    Pour tester, il faut retirer les flèches et les chiffres !!!

    Bien, on va alimenter avec un fixture. Là aussi, j'ai un peu jouer... (le samedi soir, on peut, non )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    Category:
      cat1:
        name: toto
        description: toto est là
        lvl: 1
      cat11:
        name: cat11
        description: la description de la cat11
        lvl: 2
        CategoryParent: cat1
      cat12:
        name: cat12
        description: la description de la cat12
        lvl: 2
        CategoryParent: cat1
      cat121:
        name: cat121
        description: la description de la cat121
        lvl: 2
        CategoryParent: cat12
      cat2:
        name: cat2
        description: la description de la cat2
        lvl: 1
        CategoryEnfants:
          cat21:
            name: cat21
            description: la description de la cat21
            lvl: 2
          cat22:
            name: cat22
            description: la description de la cat22
            lvl: 2
          cat23:
            name: cat23
            description: la description de la cat23
            lvl: 2
    J'ai utilisé deux possibilités d'insertions les cat1... du coté définition du parent et attribution des enfants au parent.

    Et du côté enfants où l'on définit le parents et directement dessous la collection des enfants.

    Les deux méthodes fonctionnent, aucune n'est meilleur que l'autre.


    Si on stocke la cat1 dans $cat1, on va récupérer la collection des enfants par
    $cat1->getCategoryEnfants()

    Si on stock la cat122 dans $cat122, on va récupérer son parent, cat12 par
    $cat122->getCategoryParent()
    et avec
    $cat122->getCategoryParent()->getCategoryParent() on va récupérer $cat1.

    Plus fun, avec
    $cat12->getCategoryParent()->getCategoryEnfants() on récupère la collection de ces frangins, lui compris.

    Ce n'est pas nécessairement très optimisé au niveau des requêtes.

    Tous le schema et le fixture ont été testé.
    Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).

    • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
    • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
    • Une discussion est terminée ? Alors le bouton est votre ami !

  5. #5
    Membre habitué
    Ingénieur d'études et de développement
    Inscrit en
    Juin 2009
    Messages
    112
    Détails du profil
    Informations professionnelles :
    Activité : Ingénieur d'études et de développement
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2009
    Messages : 112
    Points : 154
    Points
    154
    Par défaut
    Ouah !! Excellent c'est beaucoup plus clair maintenant. Je finis de manger, je test et je te redis ça.

    En tout cas merci beaucoup du temps que tu as passé sur mon problème

Discussions similaires

  1. Réponses: 3
    Dernier message: 31/01/2012, 19h04
  2. [Doctrine] Relation entre deux tables dans schema.yml sans contrainte
    Par ninorotto dans le forum ORM
    Réponses: 8
    Dernier message: 24/08/2011, 10h26
  3. [1.x] Probleme relation schema.yml
    Par modogo2000 dans le forum Débuter
    Réponses: 7
    Dernier message: 09/03/2011, 14h50
  4. [1.x] Relations many to many dans schema.yml
    Par titiyoyo dans le forum Symfony
    Réponses: 21
    Dernier message: 10/09/2010, 13h24
  5. schema.yml pour relation n-n Doctrine
    Par psgman113 dans le forum ORM
    Réponses: 3
    Dernier message: 22/03/2010, 19h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo