Relation ManyToOne et OneToMany

Par Theskinline01, il y a 8 ans


Bonjour,

Voila j'essais depuit un moment de faire la chose suivants: avec 2 entitées l'une Offres_servers et l'autre CategoriesOffres, j'essais en gros de charger les offres associer à leurs catégories donc une relation ManyToOne (Une categories => plusieurs Offres).
Hors je ne parvient pas à charger les offres avec les categories....voici le debug:

CategoriesOffres {#2139 ▼ -id: 30 -media: Medias {#1933 ▼ +__isInitialized__: true -id: 166 -title: "icon-minecraft_png" -path: "icon-minecraft.png" …2 } -offres: PersistentCollection {#2027 ▼ -snapshot: [] -owner: CategoriesOffres {#2139} -association: array:15 [ …15] -em: EntityManager {#400 …11} -backRefFieldName: "categories" -typeClass: ClassMetadata {#1913 …} -isDirty: false #collection: ArrayCollection {#2020 ▼ -elements: [] } #initialized: false } }

L'entité CategoriesOffres.php

<?php namespace Dinastyserv\SiteBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Doctrine\Common\Collections\ArrayCollection; /** * CategoriesOffres * * @ORM\Table(name="categories_offres") * @ORM\Entity(repositoryClass="Dinastyserv\SiteBundle\Repository\CategoriesOffresRepository") */ class CategoriesOffres { public function __construct() { $this->offres = new ArrayCollection(); } /** * @var int * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * * @ORM\OneToOne (targetEntity="Dinastyserv\SiteBundle\Entity\Medias", cascade={"persist","remove"}) * @ORM\JoinColumn(nullable=false) * */ private $media; /** * @ORM\OneToMany(targetEntity="Dinastyserv\SiteBundle\Entity\Offres_servers", mappedBy="categories", cascade={"remove"}) * @ORM\JoinColumn(nullable=true) */ private $offres; /** * @var string * * @ORM\Column(name="name", type="string", length=255) */ private $name; /** * @var string * * @ORM\Column(name="slug", type="string", length=255) */ private $slug; /** * @var string * * @ORM\Column(name="description", type="string", length=255) */ private $description; /** * @var string * * @ORM\Column(name="description_long", type="text") */ private $descriptionLong; /** * @var bool * * @ORM\Column(name="active", type="boolean") */ private $active; /** * Get id * * @return int */ public function getId() { return $this->id; } /** * Set name * * @param string $name * * @return CategoriesOffres */ public function setName($name) { $this->name = $name; return $this; } /** * Get name * * @return string */ public function getName() { return $this->name; } /** * Set description * * @param string $description * * @return CategoriesOffres */ public function setDescription($description) { $this->description = $description; return $this; } /** * Get description * * @return string */ public function getDescription() { return $this->description; } /** * Set descriptionLong * * @param string $descriptionLong * * @return CategoriesOffres */ public function setDescriptionLong($descriptionLong) { $this->descriptionLong = $descriptionLong; return $this; } /** * Get descriptionLong * * @return string */ public function getDescriptionLong() { return $this->descriptionLong; } /** * Set active * * @param boolean $active * * @return CategoriesOffres */ public function setActive($active) { $this->active = $active; return $this; } /** * Get active * * @return bool */ public function getActive() { return $this->active; } /** * Set media * * @param \Dinastyserv\SiteBundle\Entity\Medias $media * * @return CategoriesOffres */ public function setMedia(\Dinastyserv\SiteBundle\Entity\Medias $media) { $this->media = $media; return $this; } /** * Get media * * @return \Dinastyserv\SiteBundle\Entity\Medias */ public function getMedia() { return $this->media; } /** * Set slug * * @param string $slug * * @return CategoriesOffres */ public function setSlug($slug) { $this->slug = $slug; return $this; } /** * Get slug * * @return string */ public function getSlug() { return $this->slug; } /** * Add offre * * @param \Dinastyserv\SiteBundle\Entity\Offres_servers $offre * * @return CategoriesOffres */ public function addOffre(\Dinastyserv\SiteBundle\Entity\Offres_servers $offre) { $this->offres[] = $offre; return $this; } /** * Remove offre * * @param \Dinastyserv\SiteBundle\Entity\Offres_servers $offre */ public function removeOffre(\Dinastyserv\SiteBundle\Entity\Offres_servers $offre) { $this->offres->removeElement($offre); } /** * Get offres * * @return \Doctrine\Common\Collections\Collection */ public function getOffres() { return $this->offres; } }

L'entité Offres_servers.php

<?php namespace Dinastyserv\SiteBundle\Entity; use Doctrine\ORM\Mapping as ORM; /** * Offres_servers * * @ORM\Table(name="offres_servers") * @ORM\Entity(repositoryClass="Dinastyserv\SiteBundle\Repository\Offres_serversRepository") */ class Offres_servers { /** * @var int * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * * @ORM\OneToOne (targetEntity="Dinastyserv\SiteBundle\Entity\Medias", cascade={"persist","remove"}) * @ORM\JoinColumn(nullable=false) * */ private $media; /** * @ORM\ManyToOne(targetEntity="Dinastyserv\SiteBundle\Entity\CategoriesOffres", inversedBy="offres") * @ORM\JoinColumn(nullable=true) */ private $categories; /** * @var string * * @ORM\Column(name="name", type="string", length=255) */ private $name; /** * @var string * * @ORM\Column(name="description", type="string", length=255) */ private $description; /** * @var string * * @ORM\Column(name="description_long", type="text") */ private $descriptionLong; /** * @var array * * @ORM\Column(name="prix", type="array") */ private $prix; /** * @var array * * @ORM\Column(name="params", type="array") */ private $params; /** * @var array * * @ORM\Column(name="options", type="array") */ private $options; /** * @var array * * @ORM\Column(name="install", type="array") */ private $install; /** * @var bool * * @ORM\Column(name="active", type="boolean") */ private $active; /** * Get id * * @return int */ public function getId() { return $this->id; } /** * Set name * * @param string $name * * @return Offres_servers */ public function setName($name) { $this->name = $name; return $this; } /** * Get name * * @return string */ public function getName() { return $this->name; } /** * Set description * * @param string $description * * @return Offres_servers */ public function setDescription($description) { $this->description = $description; return $this; } /** * Get description * * @return string */ public function getDescription() { return $this->description; } /** * Set descriptionLong * * @param string $descriptionLong * * @return Offres_servers */ public function setDescriptionLong($descriptionLong) { $this->descriptionLong = $descriptionLong; return $this; } /** * Get descriptionLong * * @return string */ public function getDescriptionLong() { return $this->descriptionLong; } /** * Set prix * * @param array $prix * * @return Offres_servers */ public function setPrix($prix) { $this->prix = $prix; return $this; } /** * Get prix * * @return array */ public function getPrix() { return $this->prix; } /** * Set options * * @param array $options * * @return Offres_servers */ public function setOptions($options) { $this->options = $options; return $this; } /** * Get options * * @return array */ public function getOptions() { return $this->options; } /** * Set install * * @param array $install * * @return Offres_servers */ public function setInstall($install) { $this->install = $install; return $this; } /** * Get install * * @return array */ public function getInstall() { return $this->install; } /** * Set active * * @param boolean $active * * @return Offres_servers */ public function setActive($active) { $this->active = $active; return $this; } /** * Get active * * @return bool */ public function getActive() { return $this->active; } /** * Set media * * @param \Dinastyserv\SiteBundle\Entity\Medias $media * * @return Offres_servers */ public function setMedia(\Dinastyserv\SiteBundle\Entity\Medias $media) { $this->media = $media; return $this; } /** * Get media * * @return \Dinastyserv\SiteBundle\Entity\Medias */ public function getMedia() { return $this->media; } /** * Set params * * @param array $params * * @return Offres_servers */ public function setParams($params) { $this->params = $params; return $this; } /** * Get params * * @return array */ public function getParams() { return $this->params; } /** * Set categories * * @param \Dinastyserv\SiteBundle\Entity\CategoriesOffres $categories * * @return Offres_servers */ public function setCategories(\Dinastyserv\SiteBundle\Entity\CategoriesOffres $categories = null) { $this->categories = $categories; return $this; } /** * Get categories * * @return \Dinastyserv\SiteBundle\Entity\CategoriesOffres */ public function getCategories() { return $this->categories; } }

Voilà merci par avance pour votre aide :)

Décrivez ici vos erreurs ou ce que vous obtenez à la place de ce que vous attendez :(

3 réponses

yanis-git, il y a 8 ans

Salut, tu dois utilisé un repository et le queryBuilder pour tout récuperer d'un coup et éviter les multiples requêtes.

class CategoriesOffresRepository extends \Doctrine\ORM\EntityRepository { //[...] public function getCategoryAndOfferById($category_id) { $qb = $this->createQueryBuilder("c"); // te permet de craft une requête dql, cela te permet de faire des choses plus complèxes que les simples requêtes magiques habituels (find, findBy, findOneBy) $qb->addSelect('o') // ici tu ajoutes les offres associés à la requête, sans ça, la jointure sera faite par MySQL mais l'information sera pas transmise à Doctrine. ->join('c.offres','o')// ici tu fais la fameuses jointures. ->where('c.id = :id')// Tu peux mettre tes wheres comme tu le souhaites, pour l'exemple c'est un simple id = 3 par exemple. ->setParameter('id',$id); return $qb->getQuery()->getResult(); } //[...] }

Au niveau de ton nommage, dans ton entité Offres :
Remplace $categories par $categorie, en effet tu peux avoir qu'une categorie par offre si j'ai bien compris.

/** * @ORM\ManyToOne(targetEntity="Dinastyserv\SiteBundle\Entity\CategoriesOffres", inversedBy="offres") * @ORM\JoinColumn(nullable=true) */ private $categories;
Theskinline01, il y a 8 ans

Bonsoir, je te remerci pour ton aide, je vais me document sur le queryBuilder car je debute avec symfony...
Ok donc comment appeler la fonction getCategoryAndOfferById() , car si je comprend la fonction getCategoryAndOfferById() me récupère toutes les offres associer a la categories_id ?
Et si je veux faire un findAll de categoriesOffres et charger toutes les Offres associer a leurs categories je peut faire comme ça ?

public function getCategoryAndOfferAll() { $qb = $this->createQueryBuilder("c"); // te permet de craft une requête dql, cela te permet de faire des choses plus complèxes que les simples requêtes magiques habituels (find, findBy, findOneBy) $qb->addSelect('o') // ici tu ajoutes les offres associés à la requête, sans ça, la jointure sera faite par MySQL mais l'information sera pas transmise à Doctrine. ->join('c.offres','o')// ici tu fais la fameuses jointures. ->where('c.id = :id');// Tu peux mettre tes wheres comme tu le souhaites, pour l'exemple c'est un simple id = 3 par exemple. return $qb->getQuery()->getResult(); }

Bonne soirée :)

Theskinline01, il y a 8 ans

La solution :

public function getCategoryAndOfferAll() { $qb = $this->createQueryBuilder("c"); // te permet de craft une requête dql, cela te permet de faire des choses plus complèxes que les simples requêtes magiques habituels (find, findBy, findOneBy) $qb->addSelect('offres') // ici tu ajoutes les offres associés à la requête, sans ça, la jointure sera faite par MySQL mais l'information sera pas transmise à Doctrine. ->join('c.offres','offres');// ici tu fais la fameuses jointures. //->where('c.id = :id');// Tu peux mettre tes wheres comme tu le souhaites, pour l'exemple c'est un simple id = 3 par exemple. return $qb->getQuery()->getResult(); }

Merci pour ton aide :)