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 :

Nested set avec jointure [1.x]


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 Nested set avec jointure
    Bonjour,

    je viens vers vous car je n'ai rien trouvé sur le net qui puisse répondre à ma question.

    Voici mon problème.
    J'ai une table category qui est un nested set.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Category:
      actAs:
        NestedSet:
          hasManyRoots: true
          rootColumnName: root_id
      columns:
        name:
          type: string()
      relations:
        Item:
          local: id
          foreign: category_id
          type: one
    De ce fait une catégorie peut contenir plusieurs enfants ...

    J'ai également une table item qui peuvent être contenus par une catégorie.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Item:
      columns:
        name:
          type: string()
        category_id:
          type: integer
      relations:
        Category:
          local: category_id
          foreign: id
          type: one

    En utilisant (intensément) le manuel de doctrine j'ai réussi à créer mes tables dans la base et à les charger avec des données de fixtures. Tout marche très bien.

    Ensuite je voudrais afficher mon arborescence de catégorie avec les items associés aux catégories.

    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Categorie 1 
     - Item1
      - Catégorie 2
       - Item2
       - Item3
     - Catégorie 3
      - Item4
    Voici le code que j'ai utilisé:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
       //récupère toute la table categorie avec les item associés
            $q = Doctrine_Query::create()
                ->select('c.name, i.name')
                ->from('Category c')
                ->leftJoin('c.Item i')
                ->setHydrationMode(Doctrine_Core::HYDRATE_ARRAY);
     
            $treeObject = Doctrine_Core::getTable('Category')->getTree();
            $treeObject->setBaseQuery($q);
            $tree = $treeObject->fetchTree();
            $treeObject->resetBaseQuery();
            print_r($tree);
    Ceci devrait automatiquement me fournir un tableau hiérarchisé avec mes catégories et mes items. Or mon problème et que si une catégorie possèdent plusieurs items, seul le premier est stocké dans le tableau.
    J'ai vérifié la requête qui est effectué par doctrine et elle me rend toutes les catégories et tous les items associés.

    Est ce que la méthode fetchTree ne prend que le premier élément?
    Bref, je suis perdu et je n'ai plus beaucoup de cheveux

    Merci d'avance.

  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
    Jamais joué avec les arbres, même si ce n'est pas l'envie qui me manque.

    Peux-tu mettre ton fixture pour m'éviter d'en inventer un ?

    Je vais tenter de reproduire ton exemple en local et de creuser.

  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
    Encore une fois merci Mimi68

    J'ai simplifié car dans ma version les catégories peuvent dépendre d'un projet et une feature et une catégorie qui mappe plusieurs items.

    Dans notre cas on a juste des catégories contenant des items ^^

    J'ai réussi a recréer l'arborescence des catégories et des items associé en changeant l'hydratation de mes données en HYDRATE_NONE, du coup je récupère toutes les données dans un tableau non hiérarchisé. Cela marche mais j'aimerai tirer partie de la puissance de Doctrine.


    voici le schéma adapté:
    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
     
    Category:
      actAs:
        NestedSet:
          hasManyRoots: true
          rootColumnName: root_id
      columns:
        name:
          type: string()
      relations:
        Item:
          local: id
          foreign: category_id
          type: one
     
    Item:
      columns:
        name:
          type: string()
        category_id:
          type: integer
      relations:
        Category:
          local: category_id
          foreign: id
          type: one
    Et le fixture:
    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
     
    Category:
      arbre:
        name: Arbre
        children:
          1:
            name: Catégorie principale 1
            Rel: rel1
            children:
                11:
                  name: Catégorie secondaire 1
                12:
                  name: Catégorie secondaire 2
                13:
                  name: Catégorie secondaire 3
                14:
                  name: Catégorie secondaire 4
                  children:
                    141:
                      name: Catégorie tertiaire 1
                    142:
                      name: Catégorie tertiaire 2
                15:
                  name: Catégorie secondaire 5
                16:
                  name: Catégorie secondaire 6
          2:
            name: Catégorie principale 2
          3:
            name: Catégorie principale 3
            children:
                31:
                  name: Catégorie secondaire 1
                32:
                  name: Catégorie secondaire 2
                33:
                  name: Catégorie secondaire 3            
          4:
            name: Catégorie principale 4
            children:
              41:
                name: Catégorie secondaire 1
     
     
    Item:
      i1:
        name: Baseline
        Category: 11
      i2:
        name: Product
        Category: 11
      i3:
        name: Analysis
        Category: 12
      i4:
        name: Architecture
        Category: 12
      i5:
        name: Design review
        Category: 12
      i6:
        name: Feature analysis
        Category: 13
      i7:
        name: Implementation
        Category: 141
      i8:
        name: Review
        Category: 141
      i9:
        name: Test
        Category: 142
      i10:
        name: Stabilization
        Category: 16
      i11:
        name: Feature 
        Category: 16
      i12:
        name: Feature view
        Category: 2
      i13:
        name: Fixing
        Category: 2
      i14:
        name:  Repport
        Category: 41

  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
    En fait, c'est pas aussi compliqué que ce que je craignais.

    Le schema est mauvais. C'est toujours la même chose, même si ce n'est pas obligatoire, il ne faut définir une relation que d'un côté de la relation donc sur une seul des deux tables, les paramètres foreign permettent de définir ce qui se passe de l'autre côté.

    De plus, la relation entre la table Item et la table category était définie comme un "one-to-one" et ne pouvait donc retourner qu'un élément.

    Le schema corrigé :
    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
     
    Category:
      actAs:
        NestedSet:
          hasManyRoots: true
          rootColumnName: root_id
      columns:
        name:
          type: string()
     
    Item:
      columns:
        name:
          type: string()
        category_id:
          type: integer
      relations:
        Category:
          local: category_id
          foreign: id
          foreignAlias: Items
    Il a gagné en légerté et lisibilité. La déclaration de la relation est faite du côté "many" de la table, ce qui est plus simple. A noté que dans un objet ($category) de la table catégory, on va récupérer les items par $category->getItems() qui nous retournera un doctrine_collection des objets items concernés.

    Par contre, pour un objet item ($item) on a un seul objet catégory, récupéré directement par $item->getCategory().

    Toujours le truc du "s" en fin du nom de la méthode qui permet de savoir si l'on récupère un objet (pas de "s") ou une collection (un "s").


    Le fixature n'a pas changé, j'y ai juste retiré "Rel: rel1" qui doit être un artéfact du reste des tables du modèle.


    J'ai un peu modifié le code de la fonction de test.
    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
     
        public function executeIndex(sfWebRequest $request)
        {
            $q = Doctrine_Query::create()
                    ->select('c.name, i.name')
                    ->from('Category c')
                    ->leftJoin('c.Items i')
                    ->setHydrationMode(Doctrine_Core::HYDRATE_ARRAY);
     
            $treeObject = Doctrine_Core::getTable('Category')->getTree();
            $treeObject->setBaseQuery($q);
            $tree = $treeObject->fetchTree();
            $treeObject->resetBaseQuery();
            print_r($tree);
     
            echo "\n ----- test -----";
            die();
        }
    Hors le echo et le die pour en facilité l'usage, le leftJoin est devenu : "leftJoin('c.Items i')" avec un "s" à la fin de Item pour rester conforme au nouveau schema.

    Ce qui nous retourne bien tous les category correspondant à chaque item.

    Bonne chance.

  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
    Merci beaucoup ça fonctionne

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Doctrine] Comment bouger les noeud avec les Nested Set
    Par beachjf dans le forum PHP & Base de données
    Réponses: 0
    Dernier message: 10/02/2011, 21h31
  2. Réponses: 1
    Dernier message: 23/08/2010, 11h10
  3. Mise à jour de table impossible après requête avec jointure
    Par sto dans le forum Bases de données
    Réponses: 5
    Dernier message: 17/03/2004, 13h24
  4. Script avec JOINTURE et CASE
    Par Labienus dans le forum Langage SQL
    Réponses: 6
    Dernier message: 27/02/2004, 09h40
  5. problème de requête avec jointures
    Par tinhat dans le forum Requêtes
    Réponses: 7
    Dernier message: 11/08/2003, 10h33

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