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 :

[sf 1.4.x] Relation n:m avec l'admin generator


Sujet :

Symfony PHP

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 32
    Par défaut [sf 1.4.x] Relation n:m avec l'admin generator
    Bonjour,

    J'essaie depuis 2 jours de faire fonctionner correctement une relation n:m avec l'admin generator de symfony 1.4, mais quelle que soit la configuration que j'essaie dans le schema.yml, j'obtiens toujours une erreur.

    J'ai donc 3 tables (2 tables pour les données et une table de jointure entre les 2) et dans le formulaire d'édition pour ma première table, je voudrais avoir des cases à cocher qui s'affichent pour chaque possibilité (plutôt qu'une double liste à choix multiple ou une simple liste à choix multiple).

    Voici le schéma que j'ai actuellement et l'erreur qui est retournée :

    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
     
    PdtArticle:
      connection: doctrine
      tableName: pdt_article
      columns:
        id:
          type: integer(4)
          fixed: false
          unsigned: false
          primary: true
          autoincrement: true
        code_fra:
          type: string(15)
          fixed: false
          unsigned: false
          primary: false
          notnull: false
          autoincrement: false
        code_ean:
          type: string(13)
          fixed: false
          unsigned: false
          primary: false
          notnull: false
          autoincrement: false
      relations:
        pourqui:
          class: PdtPourQui
          local: id_article
          foreign: id_pour_qui
          refClass: PdtArticlePourQui
          foreignAlias: Articles
    PdtArticlePourQui:
      connection: doctrine
      tableName: pdt_article
      columns:
        id_article:
          type: integer(4)
          fixed: false
          unsigned: true
          primary: true
        id_pour_qui:
          type: integer(4)
          fixed: false
          unsigned: true
          primary: true
      relations:
        PdtArticle:
          local: id_article
          foreign: id
        PdtPourQui:
          local: id_pour_qui
          foreign: id
    PdtPourQui:
      connection: doctrine
      tableName: pdt_pour_qui
      columns:
        id:
          type: integer(4)
          fixed: false
          unsigned: true
          primary: true
          autoincrement: true
        libelle:
          type: string(255)
          fixed: false
          unsigned: false
          primary: false
          notnull: false
          autoincrement: false
      relations:
        articles:
          refClass: PdtArticlePourQui
          class: PdtArticle
          local: id_pour_qui
          foreign: id_article
          foreignAlias: Pourqui

    Et l'erreur qui est retournée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    500 | Internal Server Error | Doctrine_Exception
    Couldn't find class r
    Dans la stacktrace, voici le DQL généré :

    at Doctrine_Query_Abstract->_processDqlQueryPart('from', array('PdtArticle a', 'LEFT JOIN a.PdtTheme t', 'LEFT JOIN a.PdtTranchePrix tp', 'LEFT JOIN t.PdtUnivers u', 'LEFT JOIN r.PdtArticlePourQui PdtArticlePourQui'))

    Apparemment, l'admin generator ne traduit pas ma relation par une requête correcte mais je ne parviens pas à trouver la configuration correcte.

    Quelqu'un aurait-il une idée ?

  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
    Le problème ne provient pas du générateur d'administration mais du build de la base, a priori.

    J'ai fais quelques essais et j'arrive à un schéma simplifié, peut-être un peu trop.
    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
     
    Article:
      columns:
        code_fra: { type: string(15) }
        code_ean: { type: string(13) }
     
    Qui:
      columns:
        libelle: { type: string(255) }
     
    Groupe:
      columns:
        article_id:
          type: integer(8)
          primary: true
        qui_id:
          type: integer(8)
          primary: true
      relations:
        Article:
          foreignAlias: Quis
        Qui:
          foreignAlias: Articles
    • l'"Id" est automatiquement généré par doctrine si la table ne comporte pas de clef primaire
    • La majorité des paramètres on des valeurs par défaut, il n'est donc pas nécessaire de les renseigner et le code en est plus lisible.
    • Les relations ne nécessite l'écriture que d'un côté de la table (en principe)
    • J'ai supprimé les nom de table en camel code, pour les tests, c'est peu lisible, après il sera toujours temps de les rajouter;


    J'ai aussi monté un fichier de fixatures
    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
     
    Article:
      art1:
        code_fra: FR12345_1
        code_ean: EAN12345_1
      art2:
        code_fra: FR12345_2
        code_ean: EAN12345_2
      art3:
        code_fra: FR12345_3
        code_ean: EAN12345_3
      art4:
        code_fra: FR12345_4
        code_ean: EAN12345_4
     
    Qui:
      lib1:
        libelle: azerty_1
      lib2:
        libelle: azerty_2
      lib3:
        libelle: azerty_3
     
    Groupe:
      grp1:
        article_id: art1
        qui_id: lib1
      grp2:
        article_id: art1
        qui_id: lib2
      grp3:
        article_id: art2
        qui_id: lib2
      grp4:
        article_id: art3
        qui_id: lib3
      grp5:
        article_id: art3
        qui_id: lib1
      grp6:
        article_id: art3
        qui_id: lib2
    Mais il ne passe pas sur l'ajout dans la table "Groupe".

    Le sujet m'intéresse, je continue a explorer, si quelqu'un a une idée...

  3. #3
    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
    C'est bien ce que je craignais, pour les relations n:n il faut un peu plus de choses dans les relations qu'un simple 1:1 ou 1:n

    Le schéma de la table qui fonctionne.

    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
     
    Article:
      columns:
        code_fra: { type: string(15) }
        code_ean: { type: string(13) }
      attributes:
        export: all
        validate: true
     
    Qui:
      columns:
        libelle: { type: string(255) }
      relations:
        Articles:
          foreignAlias: Quis
          class: Article
          refClass: Groupe
     
    Groupe:
      columns:
        article_id:
          type: integer(8)
          primary: true
        qui_id:
          type: integer(8)
          primary: true
      relations:
        Article:
          foreignAlias: Groupes
        Qui:
          foreignAlias: Groupes
    • Il faut un bout de relation sur une des deux tables liées et des attributs pour l'autre.
    • J'ai lu un truc quelque part il y a quelques jours sur le site de symfony pour indiquer dans le schéma de ne pas générer de groupeForm et de groupeFilter qui ne seront jamais utilisé et économiser un peu de lourdeur. Impossible de retrouver, mais je n'ai pas non plus vraiment chercher.


    Les "fixtures" pour pouvoir tester
    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
     
    Qui:
      lib1:
        libelle: azerty_1
      lib2:
        libelle: azerty_2
      lib3:
        libelle: azerty_3
     
    Article:
      art1:
        code_fra: FR12345_1
        code_ean: EAN12345_1
        Quis: [ lib1, lib3 ]
      art2:
        code_fra: FR12345_2
        code_ean: EAN12345_2
        Quis: [lib2, lib3  ]
      art3:
        code_fra: FR12345_3
        code_ean: EAN12345_3
        Quis: [ lib3 ]
      art4:
        code_fra: FR12345_4
        code_ean: EAN12345_4
    Pour faire joli on va aussi modifier la classe qui pour qu'elle retourne le libellé dans les listes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class Qui extends BaseQui
    {
        public function __toString()
        {
            return $this->getLibelle();
        }
    }
    et la classe article pour le fra
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class Article extends BaseArticle
    {
        public function  __toString()
        {
            return $this->getCodeFra() ;
        }
    }

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

    Informations forums :
    Inscription : Janvier 2010
    Messages : 32
    Par défaut
    Merci pour la réponse mimi68. Je vais tester ça.

    Dans les relations que tu déclares dans Groupe, tu es bien sûr que symfony fait bien le lien automatiquement entre la colonne 'article_id' et la table Article et entre 'qui_id' et la table 'Qui' ?

  5. #5
    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
    Dans mes test oui.

    Il crée dans l'objet BaseQui une méthode getArticles() qui retourne la collection des articles liés.

    Idem dans BaseArticle avec getQuis().

    C'est pas beau symfony ? Sauf qu'ici c'est surtout doctrine.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 32
    Par défaut
    Merci pour ton aide mimi68!

    La relation a bien fonctionné en remplissant le schema.yml comme tu l'as fait

    Effectivement le couple Doctrine/Symfony fait bien son boulot. Par contre, étant débutant sur symfony, je trouve le "diagnostiquage" d'erreur parfois un peu ardu. J'avais essayé des configuration très ressemblantes à celle que tu m'a donné mais qui n'ont pas fonctionné...

  7. #7
    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
    Effectivement, à ce niveau, quant cela ne génère pas correctement les tables avec "symfony doctrine:build", les messages d'erreurs sont plutôt légers.

    Ma méthode consiste a créer un autre projet, vide, a faire mes test en dehors du gros projet de travail, puis, une fois le problème bien cerné, à le réintégrer dans le gros projet. J'ai donc toujours quelques répertoires testx près a accueillir mes essais.

    Encore une chose, les lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      attributes:
        export: all
        validate: true
    dans le modèle que j'ai donné ne semblent avoir aucun effet sur la relation n2n et peuvent donc être supprimées, sauf si elle sont nécessaire par ailleur.

    Amicalement,
    Michel

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 32
    Par défaut
    Merci pour l'info, je me posais la question pour ces 2 lignes effectivement.

    Par ailleurs, je me posais aussi quelques questions sur les bonnes pratiques à adopter avec symfony concernant les modifications à effectuer sur le schema / la bdd, lorsqu'on travaille avec un environnement de production dont le serveur ne peut pas être coupé, et dont la base contient des quantités importantes de données.

    Faut-il faire à chaque fois les modifications en parallèle dans le schéma et dans la base, ou bien uniquement dans la base et re-générer le schéma et les classes à chaque fois ? Tu aurais peut-être quelques conseils ou un lien intéressant à m'indiquer à ce sujet là ?

    Merci encore pour le coup de main.

    Nicolas

  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
    On sort du cadre d'un simple test de la relation n2n pour entrer de plein pied dans les stratégies de cycles de développements en entreprises.

    Tu devrais avoir 2 serveurs (au minimum) et 4 environnement (au minimum aussi) sous symfony. Sans compter un système de gestion de version.

    Environnement : développement
    Sur un serveur développement, les bases de données aussi pour évité tous risque d'intervention sur l'environnement de production accidentel.
    Il est destiné au développement. Les bases et les données doivent pouvoir être régénérées régulièrement (fixatures) pour que les tests du développeur puissent refaire régulièrement leurs tests.
    Si la structure des données (le schéma) doit être modifié, on va le tester ici.

    Environnement : test
    Sur un serveur développement, les bases de données aussi...
    Il est destiné aux tests automatique. Symfony embarque deux outils de test et il faut les utiliser en développant pour s'assurer qu'il n'y a pas de régressions lors du développement.

    Environnement : Évaluation
    Sur un serveur développement et/ou sur le serveur de production.
    Il est destiné aux tests applicatifs réalisés par les utilisateurs ou par des testeurs non développeurs.
    Les données sont en sous-ensemble des données de productions, ou des données adaptés, mais plus élaborées, généralement, que celle des deux environnement précédant.
    La base de donnée n'est jamais régénérée par un build.

    Environnement : Production
    Sur le serveur de production.
    Le plus sensible, il est destiné aux clients...
    La base de donnée n'est jamais régénérée par un build.


    Mais alors, comment va-t-on mettre a jour les évolutions de la base de données entre les versions dev et test et les deux autres ?

    Une fois qu'une évolution de la base de donnée a été mise en place et testée, on va écrire des procédures doctrine de migrations. Qui peuvent être soit écrite à la main, soit être générées par doctrine et qui permettent surtout de ne pas écraser toutes la base de données et de tout perdre. Plus d'informations ici (en anglais).. C'est une fonctionnalité que je n'ai pas encore testé à fond.

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 32
    Par défaut
    Ok, merci pour toutes ces explications. Je vais me renseigner sur tout ça.

Discussions similaires

  1. [1.x] Relations base de données en admin generator
    Par Deodys dans le forum Symfony
    Réponses: 3
    Dernier message: 14/09/2010, 11h58
  2. [1.x] édition avec l'admin generator
    Par Ryo_Saeba dans le forum Symfony
    Réponses: 1
    Dernier message: 19/08/2008, 11h59
  3. Réponses: 1
    Dernier message: 15/01/2007, 17h19
  4. Modéliser relation d'hériatge avec DTD
    Par kobe dans le forum Valider
    Réponses: 1
    Dernier message: 18/10/2005, 18h14
  5. [Hibernate3] relation 1-1 avec 2 pk
    Par mauvais_karma dans le forum Hibernate
    Réponses: 2
    Dernier message: 22/08/2005, 23h21

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