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 :

QueryBuilder et table d'association [3.x]


Sujet :

Symfony PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    .
    Inscrit en
    Avril 2016
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Avril 2016
    Messages : 108
    Par défaut QueryBuilder et table d'association
    Bonjour,

    Je cherche à lister tout mes produits ainsi que leurs suppléments ( qui sont eux même des produits ) , j'ai donc deux tables : Product et SuppProduct qui ressemble à ca :

    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
    class Product
    {
        /**
         * @ORM\Id()
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue()
         */
        private $id;
     
        /**
         * @ORM\Column(type="string")
         */
        private $name;
     
        /**
         * @ORM\Column(type="string",nullable=true)
         */
        private $description;
     
     
        /**
         * @ORM\Column(type="bigint")
         */
        private $price;
     
        /**
         * @ORM\Column(type="boolean")
         */
        private $isSupp;
     
     
        /**
         * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Category",inversedBy="products")
         */
        private $category;
     
     
        /**
         * @ORM\OneToMany(targetEntity="AppBundle\Entity\SupplementProduct",mappedBy="products")
         */
        private $products;
     
     
        /**
         * @ORM\OneToMany(targetEntity="AppBundle\Entity\SupplementProduct",mappedBy="supplements",fetch="EAGER")
         */
        private $supplements;
    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
     
    class SupplementProduct{
    /**
         * @ORM\Id() @ORM\ManyToOne(targetEntity="AppBundle\Entity\Product",inversedBy="products")
         * @ORM\JoinColumn(name="product_id", referencedColumnName="id",nullable=false,unique=true)
         */
        private $products;
     
        /**
         * @ORM\Id() @ORM\ManyToOne(targetEntity="AppBundle\Entity\Product",inversedBy="supplements")
         * @ORM\JoinColumn(name="supplement_id", referencedColumnName="id",nullable=false,unique=true)
         */
        private $supplements;
     
     
        private $product_id;
     
        private $supplement_id;
     
     
        /**
         * @ORM\Column(type="bigint",nullable=true)
         */
        private $newPrice;
    }
    Donc en BDD , je me retrouve avec une table SUppProduit : id_product,id_supp,newPrice . OK

    Donc dans mon controller je fais :
    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
     public function getAllDataAction(Request $request){
     
    //      récupere toutes les categories
            $categories = $this->getDoctrine()
                ->getRepository(Category::class)
                ->findAll();
     
     
    //      récuperer une category dans la liste
            foreach ($categories as $category){
    //            récuperer la liste de produits dans la category
                $products = $category->getProducts();
    //            récuperer un produit dans la list de produits
                foreach ($products as $product){
    //                récuperer la list de supplément associé
                    $listSupp = $this->getDoctrine()->getRepository(SupplementProduct::class)
                        ->findBy([
                            "products" =>$product,
     
                        ]);
                    foreach ( $listSupp as $supp){
                        if ($listSupp != null){
    //                        dump($listSupp);die();
    //                      pour chaque supplément trouver au produit on ajoute
                              $product->addSupplement($supp);
     
                            }
     
    //                        dump($product);die();
     
                    }
     
     
     
     
                }
            }
     
     
            return $categories;
        }

    Mais le probleme c'est que de cette facon un ProduitPrincipal qui a été lié comme supplément me retourne son propre id :
    Nom : symfony.PNG
Affichages : 892
Taille : 8,6 Ko

    Je cherche à faire une requete du style :

    SELECT supplement_id, new_price FROM `supplement_product` INNER JOIN products WHERE products.id= $id AND products.id = product_id

    Donc j'aimerai taper uniquement sur la colonne product_id comme ca si un Product: Frite par exemple est lié en tant que supplément il ressortira pour le produit associé, mais en tant que produit principal je n'aurai pas de supplément.

    Le problème c'est que au niveau objet je ne vois pas du tout comment faire ca etant donné que ma classe SuppProduct dispose de newPrice et ma table Product de $product et $supplément, j'ai du mal a faire la liaison pour arriver a un tel résultat !

    Si quelqu'un est à l'aise avec ca et peux m'expliquer!

  2. #2
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2003
    Messages
    307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2003
    Messages : 307
    Par défaut
    Tu as plusieurs fois :

    sur ta class supplément ce n'est pas normal...

  3. #3
    Membre confirmé
    Homme Profil pro
    .
    Inscrit en
    Avril 2016
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Avril 2016
    Messages : 108
    Par défaut
    Oui c'est pour avoir une clé primaire composé des deux clés étrangères, je n'ai eu aucun soucis sur le mapping ni par la suite d'ailleurs

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2003
    Messages
    307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2003
    Messages : 307
    Par défaut
    Tu sais donner un exemple de produits parce que je pense que ta structure de base n'est pas bonne

    Vol au vent un produit, une frite peut être proposée parmi les suppléments, si on prends une frite en supplément le prix diffère d'une frite en produit de base ??

  5. #5
    Membre confirmé
    Homme Profil pro
    .
    Inscrit en
    Avril 2016
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Avril 2016
    Messages : 108
    Par défaut
    C'est exactement ça, en fait au début je vais avoir par exemple 3 categories :
    Burger :
    1-burger1 (5E)
    2-burger2 (5.5)

    Pizza :
    3-4fromages (9E)
    4- napolitaine (8.5)

    Accompagnement:
    8-Frites (3.5)
    9-Potatoes (4.5)

    Donc la je n'ai que des produits principaux et de toute façon un 'supplément' sera toujours un Product à la base.
    Maintenant le but est en effet de pouvoir lier 2produits ensemble et d'ajouter un nouveau prix, le but n'étant pas de modifier le prix de produit de base.
    Si un burger n'a pas de supplément, un client pourra toujours prendre une frite en plus mais sans notion de supplément et de menu, il la paiera 3.5.


    D'ou la table SupplementProduct, ou j'ai : product_id ,supplement_id,newPrice.

    De cette façon, quand je vais lier un hamburger à une frite, le principe serait donc d'aller voir dans cette table quelle est l'id_supp lié à mon produit pour récuperer ses infos et ensuite injecterer le newPrice à la place du prix de base du produit.

    Comme ca, je pourrai crée des menus tu vois?

    Par exemple pour l'instant j'ai ca en Bdd :


    Nom : bdd.PNG
Affichages : 819
Taille : 10,8 Ko

    Mais le probleme est que du coup quand je récupere ma liste de tout mes produits, j'ai bien les suppléments pour les burgers mais j'ai aussi des suppléments pour mes frites qui pointent sur elle même et ce comportement que je n'arrive pas à résoudre!
    Je me suis rendu compte hier avec les requêtes personnalisées que quand je tape uniquement sur la colonne product_id le problème est le même, la frite me renvoie bien un tableau vide car elle n'apparait pas dans product_id.

    Je pense que ca vient de la sérialization quand je fais :
    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
    AppBundle\Entity\Product:
       attributes:
          id:
             groups: ['product','category','supplement']
          name:
             groups: ['product','category','supplement']
          description:
             groups: ['product','category','supplement']
          price:
             groups: ['product','category','supplement']
          is_supp:
             groups: ['product','category','supplement']
          supplements:
            groups:  ['product','category']
     
    AppBundle\Entity\SupplementProduct:
       attributes:
          newPrice:
             groups: ['product','supplement','category']
          supplement_id:
             groups: ['product','category']
    Mais la honnetement ca fait un moment que je me casse les dents dessus à tout tenter en vain !
    Désolé pour le pavé mais si quelqu'un trouve une solution il m'aura vraiment sortit de la m*** sur ce coup la !

  6. #6
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2003
    Messages
    307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2003
    Messages : 307
    Par défaut
    Bon voila sur quoi je partirais comme entité

    J'ai mis une contrainte sql pour ne pas qu'un même supplément ne soit pas présent deux fois sur un même produit

    Reste à trouver en sql si on sait empêcher qu'un supplément soit supplément de lui meme
    Donc que parent_product_id != produit_id

    J'ai mis tes prix en décimal sinon tu va avoir des problèmes ^-^

    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
     
    /**
     * Produit
     * @ORM\Table(name="produit")
     * @ORM\Entity(repositoryClass="ProductRepository")
     *
     */
    class Product
    {
        /**
         * @ORM\Id()
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue()
         */
        private $id;
     
        /**
         * @ORM\Column(type="string")
         */
        private $name;
     
        /**
         * @ORM\Column(type="string",nullable=true)
         */
        private $description;
     
        /**
         * @ORM\Column(type="decimal", precision=4, scale=2, nullable=false)
         */
        private $price;
     
        /**
         * @ORM\Column(type="boolean", nullable=false, options={"default" = "0"})
         */
        private $isSupp;
     
        /**
         * @ORM\OneToMany(targetEntity="SupplementProduct",mappedBy="parent_product")
         */
        private $supplements;
    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
     
     
    /**
     * Supp
     * @ORM\Table(name="produit_supplements", uniqueConstraints={
     *     @ORM\UniqueConstraint(columns={"parent_product_id", "produit_id"})
     * })
     * @ORM\Entity()
     *
     */
    class SupplementProduct
    {
        /**
         * @ORM\Id()
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue()
         */
        private $id;
     
        /**
         *
         * @ORM\ManyToOne(targetEntity="Product",inversedBy="supplements")
         * @ORM\JoinColumn(nullable=false)
         */
        private $parent_product;
     
        /**
         *
         * @ORM\ManyToOne(targetEntity="Product")
         *
         */
        private $produit;
     
        /**
         * @ORM\Column(type="decimal", precision=4, scale=2, nullable=false)
         */
        private $newPrice;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    $produits = $em->getRepository(Product::class)->findAll();
            foreach ($produits as $product){
                foreach ($product->getSupplements() as $supplement) {
                    $produit = $supplement->getProduit();
                    $price = $supplement->getNewPrice();
                }
            }

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

Discussions similaires

  1. Mapper table d'association many-to-many
    Par zaineb.z dans le forum Hibernate
    Réponses: 13
    Dernier message: 23/06/2007, 20h09
  2. Réponses: 1
    Dernier message: 20/06/2007, 13h36
  3. [HIBERNATE] requete avec table d'association
    Par zybay dans le forum Hibernate
    Réponses: 1
    Dernier message: 14/06/2007, 12h59
  4. Problème de table d'association dans un DBGrid
    Par Mestoph dans le forum Bases de données
    Réponses: 5
    Dernier message: 30/03/2007, 17h17
  5. [MySQL] Problème d'insertion de données dans table d'associations
    Par Yukhaa dans le forum PHP & Base de données
    Réponses: 13
    Dernier message: 07/02/2006, 17h10

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