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 :

Affichage de tables liées


Sujet :

Symfony PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 14
    Par défaut Affichage de tables liées
    Bonjour.
    Je débute sur Symfony (1.4) et je ne sais pas comment faire pour afficher (proprement) des données d'une table liée.

    Je m'explique (je copie mon schema.yml par la suite) :
    J'ai créé le module client et l'affichage de la liste des clients avec les données de la table se fait correctement.
    Je voudrai pouvoir afficher le nom de la civilité et non son ID ainsi que le nom du type de personne et non son ID.

    J'y arrive en rajoutant ce code dans indexSuccess.php (pour le type) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <td class="typepersonne"><?php echo Doctrine::getTable('typePersonne')->find($client->getTypePersonneId())->getName() ?></td>
    Mais cela ne me semble pas très propre vu que ce code se trouve dans la vue et ne respecte donc pas le MVC. Comment faire pour arranger ça ?

    D'autre part, je voudrais pouvoir afficher dans la ligne correspondant au client, ces différentes adresses, téléphones, emails..., avec leur type aussi.
    En gros, je voudrais toutes les infos, ou presque, sur la même ligne.
    Et la je ne sais pas trop comment faire.

    Est-ce que quelqu'un peut me donner un coup de main ?

    Voici le 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
    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
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    ---
    detect_relations: true
    options:
      charset: utf8
      type: InnoDB
     
    client:
      actAs:
        Timestampable: ~
      columns:
        id:
          type: integer(4)
          primary: true
          notnull: true
          autoincrement: true
        lastname:
          type: string(60)
          notnull: true
        firstname:
          type: string(60)
          notnull: true
        birth_date:
          type: date
        birth_hour:
          type: time
        birth_place:
          type: string(60)
        independance_date:
          type: date
        civilite_id:
          type: integer(4)
          notnull: true
        type_personne_id:
          type: integer(4)
          notnull: true
      relations:
        civilite:
          class: civilite
          local: civilite_id
          foreign: id
          foreignAlias: clients
        typePersonne:
          class: typePersonne
          local: type_personne_id
          foreign: id
          foreignAlias: clients
      indexes:
        fk_client_civilite:
          fields: [civilite_id]
        fk_client_type_personne1:
          fields: [type_personne_id]
     
    civilite:
      actAs:
        Timestampable: ~
      columns:
        id:
          type: integer(4)
          primary: true
          notnull: true
          autoincrement: true
        long_name:
          type: string(45)
        name:
          type: string(45)
     
    adresse:
      actAs:
        Timestampable: ~
      columns:
        id:
          type: integer(4)
          primary: true
          notnull: true
          autoincrement: true
        street:
          type: string(45)
        zip:
          type: string(45)
        city:
          type: string(45)
        client_id:
          type: integer(4)
          primary: true
          notnull: true
        type_adresse_id:
          type: integer(4)
          notnull: true
      relations:
        client:
          class: client
          local: client_id
          foreign: id
          foreignAlias: adresses
          onDelete: cascade
        typeAdresse:
          class: typeAdresse
          local: type_adresse_id
          foreign: id
          foreignAlias: adresses
      indexes:
        fk_adresse_client1:
          fields: [client_id]
        fk_adresse_type_adresse1:
          fields: [type_adresse_id]
     
    typeAdresse:
      actAs:
        Timestampable: ~
      tableName: type_adresse
      columns:
        id:
          type: integer(4)
          primary: true
          notnull: true
          autoincrement: true
        name:
          type: string(45)
          notnull: true
     
    telephone:
      actAs:
        Timestampable: ~
      columns:
        id:
          type: integer(4)
          primary: true
          notnull: true
          autoincrement: true
        number:
          type: string(45)
          notnull: true
        client_id:
          type: integer(4)
          primary: true
          notnull: true
        type_telephone_id:
          type: integer(4)
          notnull: true
      relations:
        client:
          class: client
          local: client_id
          foreign: id
          foreignAlias: telephones
          onDelete: cascade
        typeTelephone:
          class: typeTelephone
          local: type_telephone_id
          foreign: id
          foreignAlias: telephones
      indexes:
        fk_telephone_client1:
          fields: [client_id]
        fk_telephone_type_telephone1:
          fields: [type_telephone_id]
     
    typeTelephone:
      actAs:
        Timestampable: ~
      tableName: type_telephone
      columns:
        id:
          type: integer(4)
          primary: true
          notnull: true
          autoincrement: true
        name:
          type: string(45)
          notnull: true
     
    email:
      actAs:
        Timestampable: ~
      columns:
        id:
          type: integer(4)
          primary: true
          notnull: true
          autoincrement: true
        email:
          type: string(50)
          notnull: true
        client_id:
          type: integer(4)
          primary: true
          notnull: true
        type_email_id:
          type: integer(4)
          notnull: true
      relations:
        client:
          class: client
          local: client_id
          foreign: id
          foreignAlias: emails
          onDelete: cascade
        typeEmail:
          class: typeEmail
          local: type_email_id
          foreign: id
          foreignAlias: emails
      indexes:
        fk_email_client1:
          fields: [client_id]
        fk_email_type_email1:
          fields: [type_email_id]
     
    typeEmail:
      actAs:
        Timestampable: ~
      tableName: type_email
      columns:
        id:
          type: integer(4)
          primary: true
          notnull: true
          autoincrement: true
        name:
          type: string(45)
          notnull: true
     
    typePersonne:
      actAs:
        Timestampable: ~
      tableName: type_personne
      columns:
        id:
          type: integer(4)
          primary: true
          notnull: true
          autoincrement: true
        long_name:
          type: string(45)
        name:
          type: string(45)
    Il a été généré par un plugin de MysqlWorkBench.

    Merci pour votre aide.

    Eric

    P.S : au besoin je peux fournir le schéma UML de la base.

  2. #2
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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
    Par défaut
    Il faudrait savoir comment tu as créé le "module".

    Le cas échéant le generator.yml et les fichiers que tu as modifiés.

    Si non, le fichier actions.class.php et le template impacté par la demande.

    Le schéma est impressionnant, c'est la première fois que j'en vois un généré par un modélisateur et qui soit viable niveau du yml généré, j'en ai téléchargé l'outil pour le tester...

    Juste un truc qui me chiffonne, dans la table "adresse" tu as une clef primaire composée avec 'id' et 'client_id'. Vu que 'id' est unique, je ne vois pas l'intérêt d'une clef composer, sauf à générer des problèmes.

    J'attends les fichiers pour t'aider.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Si ta relation est bien définie ( et à première vue ça semble être le cas ), il te suffit de mettre dans ta vue :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <td class="typepersonne"><?php echo $client->getTypePersonne()->getName() ?></td>
    Pour tes adresses, vu qu'on est dans une relation 1-n, le code sera du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <?php foreach ($client->getAdresses() as $adresse): ?>
      <?php echo $adresse->getStreet() ?> ... 
      Pour te faciliter la vie, tu peux définir dans Adresse.class.php un getter personnalisé qui te renvoie toutes les données de ton adresse
    <?php endforeach; ?>
    J'ai répondu en résumé à tes questions, si tu as besoin de plus d'info n'hésites pas à demander

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 14
    Par défaut
    @yotsumi :
    Wow, MERCI ! En fait c'est super simple. Ça marche nickel !!!
    Et le couplage des 2 pour avoir le type d'adresse aussi.

    Maintenant, je vais m'attaquer aux formulaires de création et de modification. Peut être que je reviendrai poser quelques question ici

    @mimi68 :
    Le plugin pour MysqlWorkBench est Doctrine Export 0.4.1. J'ai du rajouter les actAs par contre.
    Dans la table adresse il y a effectivement un clé composée. Adresse est une propriété multivaluée de client (pour avoir plusieurs adresses par client si besoin). c'est pour ça qu'on retrouve la FK client_id.

    Sinon j'ai généré tous les fichiers avec l'exécutable symfony.

    Veux-tu quand même les autres fichiers ?

  5. #5
    Invité
    Invité(e)
    Par défaut
    Ce que veut dire mimi68, c'est que sur ta table adresse, tu as mis client_id en clé primaire.
    Tu as donc sur cette table un couple de clés primaires ( clé primaire composée ):
    - id : clé primaire auto-incrémentée
    - client_id : clé étrangère, que tu force en clé primaire

    Vu que la colonne id est auto-incrémentée, tu n'as pas besoin de définir client_id comme seconde clé primaire, ça n'apporte rien et pourrait au contraire générer des ennuis (avec doctrine notamment).

    Idem pour telephone, email ...

  6. #6
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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
    Par défaut
    Non, si la réponse de yotsumi te va, elle me va.

    Juste une chose, il faut savoir qu'utiliser un $client->getTypePersonne()->getName() génère une requête SQL supplémentaire, il peut être intéressant, suivant le cas, de modifier la requêtes initial pour éviter une abondance de requêtes.

    Et tu peux faire un peu plus court avec $client->getTypePersonne() si tu as mis une méthode magique __toString sur l'objet du modèle TypePersonne qui retourne le nom.


    Pour l'adresse, toujours si cette méthode te convient, plutôt qu'un get spécialisé qui serait "un peu" hors MVC je définirais plutôt un partiel pour garder un code lisible.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <?php foreach ($client->getAdresses() as $adresse): ?>
      <?php include_partiel('AfficheAdresse', 'adresse' => $adresse) ?> 
    <?php endforeach; ?>
    Et le partial _AfficheAdresse
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <div id="adresse_<?php echo $adresse->getId() ?>" class="adresse" > 
       <p><?php echo $adresse->getStreet() ?></p>
       <p><?php echo $adresse->getCP() ?> <?php echo $adresse->getCity() ?></p>
    </div>

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 14
    Par défaut
    Je n'avais pas bien compris le fonctionnement de __toString(). Maintenant je vois et c'est pas mal du tout, ça simplifie bien les choses en effet.
    Je n'avais pas du tout pensé au partiel. Je vais essayer ça !

    J'ai bien pensé à modifier la requête initiale, mais je ne vois pas du tout comment faire. Est-ce qu'il y a un moyen de tout récupérer d'un coup pour n'avoir qu'à l'afficher ensuite ?

    En ce qui concerne la seconde clé primaire, elle est issue du MCD Merise. Est-ce qu'elle va vraiment gêner Doctrine ? Si oui, je la laisse en FK uniquement alors.

    Merci pour tous vos conseils

  8. #8
    Invité
    Invité(e)
    Par défaut
    J'abonde dans le sens du partial

  9. #9
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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
    Par défaut
    Oui, tu as intérêt, si c'est réalisable, à récupérer toutes les informations dans une seule requête.

    Dans le genre (les nom sont imaginaires) dans ton modèle Client
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public function getOneTPAndAdresses($id)
    {
       $q = doctrine_query::create()->
                select('client c')->
                leftJoint('c.typePersonne t')->
                leftJoint('c.Adresses a')->
                where('c.id = ?', $id);
       return $q->fetchall();
    }
    De tête et non testé.

    Avec cela, tu devrais tous récupérer d'un coup.


    Pour ce qui est des clefs primaires, l'expérience avec Doctrine m'a appris que : plus tu as des clefs primaires multiples sur des tables, plus tu as des problèmes. Pour le coup, t'as deux avis identiques...

    Maintenant, tu fais comme tu veux...

Discussions similaires

  1. [Lazarus] Affichage de deux tables liées dans un DBGrid
    Par sadl65 dans le forum Lazarus
    Réponses: 2
    Dernier message: 03/01/2011, 13h34
  2. Affichage Etat tables liées
    Par David42000 dans le forum IHM
    Réponses: 4
    Dernier message: 15/07/2009, 16h17
  3. Affichage sur 2 tables liées
    Par Laurent75017 dans le forum Requêtes
    Réponses: 13
    Dernier message: 04/02/2009, 14h43
  4. Réponses: 6
    Dernier message: 12/10/2008, 20h03
  5. formulaire affichage tables liées
    Par papagei2 dans le forum IHM
    Réponses: 16
    Dernier message: 06/10/2007, 16h38

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