[Symfony2] Doctrine:HYDRATE_ARRAY et relation OneToMany

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

11 févr. 2013, 12:01

Salut,

petit soucis encore une fois qui semble simple mais que je n'arrive pas à dépasser, j'ai ce modèle:

Cours 1,n <-------------> 1,n Professeurs (Un professeur peut donner plusieurs cours, un cours peut-être donné par plusieurs professeurs, genre une semaine l'un une semaine l'autre).

Pour générer la liste j'ai fait ma petite requête DQL en utilisant HYDRATE_ARRAY. Problème, un de mes cours à deux professeurs je me retrouve donc avec deux fois la même ligne, ayant juste le professeur qui change.

J'ai essayé de faire un petit pré-traitement (entre la retour de la requête et l'envoi au template) en parcourant les lignes et en ajoutant une entrée à mon tableau de données, une cellule "teachers" contenant elle-même un tableau avec 1 ou n profs, afin de regrouper les professeurs dans une même ligne de cours, et en supprimant les autres.

Problème: si mon tableau semble correctement généré, j'ai une erreur à l'affichage du template me disant que la clé "teachers" n'existe pas, avec la liste des clés existantes qui sont les colonnes spécifiées dans la requête.

Cela vous paraît-il normal ou serait-ce simplement une erreur de ma part ?

Auriez-vous une meilleure technique pour gérer les doublons de lignes renvoyées avec une association OneToMany?

Je n'ai pas le code ni le message d'erreur exact pour le moment mais je pourrai le copier plus tard

Merci :)

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

11 févr. 2013, 14:28

A quoi ressemble ton tableau ? Tu as essayé un bête var_dump() dessus ?
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

11 févr. 2013, 15:12

A quoi ressemble ton tableau ? Tu as essayé un bête var_dump() dessus ?
Oui, c'est justement avec un var_dump que je vois que ma cellule 'teachers' est ajoutée, à la suite des autres, d'où mon incompréhension sur ce message d'erreur.

Je le posterai dès que j'aurai le code sous les yeux.

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

12 févr. 2013, 01:48

Voici donc ma requête:
    public function loadAll($semesterId) {
        $q = $this
            ->createQueryBuilder('c')
            ->addSelect('c.id as course_id, c.dayOfWeek, c.startTime, c.endTime, c.alternateStartdate, c.alternateEnddate')
            ->addSelect('r.name as classroom, c2.label as classlevel')
            ->addSelect('t.id as teacher_id, t.lastName as teacher_lastName, t.firstName as teacher_firstName')
            ->innerJoin('c.teachers', 't')
            ->innerJoin('c.classLevel', 'c2')
            ->innerJoin('c.classRoom', 'r')
            ->innerJoin('c.semester', 's')
            ->where('s.id = :semesterId')
            ->add('orderBy', 'c.dayOfWeek ASC, c.startTime ASC')
            ->setParameter('semesterId', $semesterId)
            ->getQuery()
        ;
        $results = $q->execute(array(), Query::HYDRATE_ARRAY);
        
        return $results;   
    }
Le tableau généré:
array(6) {
  [0] =>
  array(13) {
    [0] =>
    array(6) {
      'id' =>
      int(326)
      'dayOfWeek' =>
      int(2)
      'startTime' =>
      class DateTime#1902 (3) {
        ...
      }
      'endTime' =>
      class DateTime#1900 (3) {
        ...
      }
      'alternateStartdate' =>
      NULL
      'alternateEnddate' =>
      NULL
    }
    'course_id' =>
    int(326)
    'dayOfWeek' =>
    int(2)
    'startTime' =>
    class DateTime#1898 (3) {
      public $date =>
      string(19) "2013-02-11 10:00:00"
      public $timezone_type =>
      int(3)
      public $timezone =>
      string(16) "America/New_York"
    }
    'endTime' =>
    class DateTime#1888 (3) {
      public $date =>
      string(19) "2013-02-11 11:30:00"
      public $timezone_type =>
      int(3)
      public $timezone =>
      string(16) "America/New_York"
    }
    'alternateStartdate' =>
    NULL
    'alternateEnddate' =>
    NULL
    'classroom' =>
    string(14) "Salle de cours"
    'classlevel' =>
    string(2) "A2"
    'teacher_id' =>
    int(3554)
    'teacher_lastName' =>
    string(7) "Keating"
    'teacher_firstName' =>
    string(4) "John"
    'teachers' =>
    array(1) {
      [0] =>
      array(3) {
        ...
      }
    }
  }
[...]}
Le bout du template concerné:
                <ul>
                {% for teacher in entity['teachers'] %}
                    <li><a href="{{ path('teacher_show', { 'id': teacher['teacher_id'] }) }}">{{ teacher['teacher_lastName'] }}</a></li>
                {% endfor %}
                </ul>
Et le message d'erreur que j'ai :
Key "teachers" for array with keys "0, course_id, dayOfWeek, startTime, endTime, alternateStartdate, alternateEnddate, classroom, classlevel, teacher_id, teacher_lastName, teacher_firstName" does not exist in /home/guillaume/public_html/Virgule/src/Virgule/Bundle/MainBundle/Resources/views/Course/index.html.twig at line 30
Donc je ne comprends pas bien, j'ai pourtant l'impression que dans la cellule 'teachers' j'ai un autre tableau sur lequel je devrais pouvoir itérer facilement... une idée ?

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

12 févr. 2013, 08:48

Je ne vois pas d'erreur dans ce que j'ai sous les yeux.
Du côté du traitement supplémentaire, tu es sûr de retourner la bonne variable, de tout passer correctement jusqu'au template ?
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

12 févr. 2013, 11:54

Du côté du traitement supplémentaire, tu es sûr de retourner la bonne variable, de tout passer correctement jusqu'au template ?
Ecoute on n'est jamais sûr mais je ne vois pas de problème, mon traitement ne fait qu'ajouter des données au tableau, et ensuite je fais le return, sans même passer par ma méthode de pagination pour le moment. Et j'affiche bien le reste du tableau dans mon template.

Mais bon en fait, j'ai réglé mon problème en utilisant un deuxième tableau, ça fonctionne, et c'est beaucoup plus simple à générer, je n'y avais pas pensé :)

Merci pour ton aide.