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 :

embedForms 1:n avec table intermédiaire [1.x]


Sujet :

Symfony PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Par défaut embedForms 1:n avec table intermédiaire
    Ladies and gentlemen,

    Soit une gestion de catalogue simplifiée : j'ai des objets Category, Product, Image. Une catégorie ou un produit a 1:n images, une image n'appartient qu'à un seul élément de type donné (produit ou image).

    Utiliser une relation 1:n classique en mettant la clé étrangère dans la table Image n'est pas satisfaisant ici car on ne sait pas quelle table va référencer cette clé étrangère.

    C'est pourquoi une table intermédiaire est introduite : CategoryImage qui lie une image à sa catégorie, ProductImage qui lie une image à son produit.

    Si on ne considère que le côté 'catégorie', cela nous donne un schéma (simplifié) comme ceci :
    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:
      columns:
        name:
          type: string(45)
          notnull: true
      relations:
        Images:
          refClass: CategoryImage
          class: Image
          foreignType: one
     
    CategoryImage:
      columns:
        image_id:
          type: integer
          primary: true
        category_id:
          type: integer
          notnull: true
     
    Image:
      columns:
        file_name:
          type: string(255)
          notnull: true
          unique: true
    Une fois généré le modèle, les cardinalités indiquées dans le code sont correctes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    BaseCategory::setUp() {
            $this->hasMany('Image as Images', array(
                 'refClass' => 'CategoryImage',
                 'local' => 'category_id',
                 'foreign' => 'image_id'));
    }
     
    BaseImage::setUp() {
            $this->hasOne('Category', array(
                 'refClass' => 'CategoryImage',
                 'local' => 'image_id',
                 'foreign' => 'category_id'));
    }
    Tout à coup, l'envie irrépressible me saisit : je veux encapsuler un formulaire sur les Images dans la page de gestion des catégories !

    Je prépare aussitôt l'objet Image de la façon la plus banale qui soit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	$img = new Image();
    	$img->setCategory($cat);
    Et là, soudain, paf ! Le drame :
    Couldn't call Doctrine_Core::set(), second argument should be an instance of Doctrine_Collection when setting many-to-many references.
    Face à cette injustice, je ne suis plus qu'un cri : Pourrrrrrrrrrrrrrrrrrrrrrquoiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii ?

    Hein ?

  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
    Ton schéma et code qui en découlent me semblent compliqué.

    Je te propose d'utiliser l'héritage pour simplifier le schéma, le code et ton travail...

    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
     
    category:
      columns:
        name:
          type: string(45)
          notnull: true
     
    product:
      columns:
        name:
          type: string(45)
          notnull: true
     
    image:
      columns:
        file_name:
          type: string(255)
          notnull: true
          unique: true
        link_id: integer
     
    image_product
        inheritance:
          extends: image
          type: column_aggregation
          keyField: type
          keyValue: 1
       relations:
          product:
             local: link_id
             foreign: id
             foreignAlias: images
     
    image_category
        inheritance:
          extends: image
          type: column_aggregation
          keyField: type
          keyValue: 2
       relations:
          category:
             local: link_id
             foreign: id
             foreignAlias: images
    Ce qui va te générer des modèles avec héritages et des forms avec héritage itou.

    Il n'y a plus qu'à encapsuler ton form imageProductForm dans le productForm.

    Pour retrouver les images d'un produit :
    $produit->getImages().

    En fait, tu ne vas jamais travailler directement avec le modèle image, mais avec un de deux hérités. Pour retrouver le produits d'une image, tu instancie l'image depuis imageProduct en $prodImage (par exemple) et tu retrouves le produit par :
    $prodImage->getProduct()

    Code simplifié et maintenance simplifiée que demande le peuple ?

  3. #3
    Membre émérite Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Par défaut
    Très juste. Je n'avais pas encore utilise les héritages de Doctrine, une bonne occasion de m'y mettre. Ca marche et c'est immensément plus simple en effet !

    J'ai juste pris la stratégie 'concrete' plutôt que 'colum-aggregation' car j'aime bien les clés étrangères typées et je n'aime pas les typages par qualifiants (colonne 'type' ici). C'est plus propre côté gestion des clés étrangères & c'est plus proche du modèle orienté objet.

    Merci pour la piste !

  4. #4
    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
    Ce que tu dis n'est pas faux.

    Par contre, tu vas te retrouver avec trois tables, une pour chaque liaison et une qui ne sert à rien, mais est, malgré tout, créé.

    C'est pour cela, entre autre, que, dans ce type de cas, je prends la solution que j'ai proposé. Toutes les données d'un même type sont dans une table et une seule, et, pour moi, ce type de mise en œuvres est bien conformes aux 5 formes normales (Ah les anciens et leur normes)...

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

Discussions similaires

  1. Jointure N-N avec table intermédiaire
    Par aspiman dans le forum Requêtes
    Réponses: 3
    Dernier message: 27/10/2018, 03h14
  2. [MySQL] Affichage profil complet avec tables intermédiaires multiples
    Par safraga dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 26/09/2014, 00h06
  3. contrainte d'intégrité avec table intermédiaire
    Par Shatter dans le forum Débuter
    Réponses: 2
    Dernier message: 12/03/2011, 19h45
  4. Requête avec table intermédiaire
    Par jgfa9 dans le forum Requêtes
    Réponses: 3
    Dernier message: 19/03/2007, 18h51
  5. Réponses: 2
    Dernier message: 02/08/2006, 10h25

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