manyToMany avec attributs et repository
Bonjour,
j'ai 2 tables: advert et skill
advert
Code:
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
|
<?php
namespace test\tutoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* Advert
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="test\tutoBundle\Entity\AdvertRepository")
* @ORM\hasLifecycleCallbacks
*/
class Advert
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* @ORM\OneToMany(targetEntity="test\tutoBundle\Entity\AdvertSkill", mappedBy="Advert")
*/
private $advertSkills;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* @param string $title
* @return Advert
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Constructor
*/
public function __construct()
{
$this->advertSkills = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add advertSkills
*
* @param \test\tutoBundle\Entity\AdvertSkill $advertSkills
* @return Advert
*/
public function addAdvertSkill(\test\tutoBundle\Entity\AdvertSkill $advertSkills)
{
$this->advertSkills[] = $advertSkills;
return $this;
}
/**
* Remove advertSkills
*
* @param \test\tutoBundle\Entity\AdvertSkill $advertSkills
*/
public function removeAdvertSkill(\test\tutoBundle\Entity\AdvertSkill $advertSkills)
{
$this->advertSkills->removeElement($advertSkills);
}
/**
* Get advertSkills
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getAdvertSkills()
{
return $this->advertSkills;
}
} |
skill
Code:
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
|
<?php
namespace test\tutoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Skill
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="test\tutoBundle\Entity\SkillRepository")
*/
class Skill
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return Skill
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
} |
mon manytomany AdvertSkill avec attributs soit 2 manyToOne
Code:
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
|
<?php
namespace test\tutoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* AdvertSkill
*
* @ORM\Table()
* @ORM\Entity
*/
class AdvertSkill
{
/**
* @ORM\ManyToOne(targetEntity="test\tutoBundle\Entity\Advert", inversedBy="advertSkills")
*/
private $Advert;
/**
* @ORM\ManyToOne(targetEntity="test\tutoBundle\Entity\Skill")
*/
private $Skill;
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="level", type="string", length=255)
*/
private $level;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set level
*
* @param string $level
* @return AdvertSkill
*/
public function setLevel($level)
{
$this->level = $level;
return $this;
}
/**
* Get level
*
* @return string
*/
public function getLevel()
{
return $this->level;
}
/**
* Set Advert
*
* @param \test\tutoBundle\Entity\Advert $advert
* @return AdvertSkill
*/
public function setAdvert(\test\tutoBundle\Entity\Advert $advert = null)
{
$this->Advert = $advert;
return $this;
}
/**
* Get Advert
*
* @return \test\tutoBundle\Entity\Advert
*/
public function getAdvert()
{
return $this->Advert;
}
/**
* Set Skill
*
* @param \test\tutoBundle\Entity\Skill $skill
* @return AdvertSkill
*/
public function setSkill(\test\tutoBundle\Entity\Skill $skill = null)
{
$this->Skill = $skill;
return $this;
}
/**
* Get Skill
*
* @return \test\tutoBundle\Entity\Skill
*/
public function getSkill()
{
return $this->Skill;
}
} |
controller
Code:
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
|
<?php
namespace test\tutoBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\component\httpFoundation\response;
use Symfony\component\httpFoundation\request;
use test\tutoBundle\Entity\Advert;
use test\tutoBundle\Entity\AdvertSkill;
class DefaultController extends Controller
{
// lecture des lignes advertSkill
public function AdvertsAction()
{
$em = $this->getDoctrine()->getManager();
$adverts = $em->getRepository("tutoBundle:advert")->getAdvertWithSkill();
// $skills = $em->getRepository("tutoBundle:AdvertSkill")->findAll();
return $this->render('tutoBundle:Default:Advert.html.twig', array("adverts"=>$adverts));
}
// creation d'un advert
public function AdvertCreateAction(request $request)
{
$em = $this->getDoctrine()->getManager();
if($request->isMethod("POST"))
{
// echo "<pre>".print_r($request->request,true);
$advertAdd = new Advert();
$advertAdd->setTitle($_POST["title"]);
$em->persist($advertAdd);
$em->flush();
return $this->redirect($this->generateUrl("Adverts"));
}
return $this->render('tutoBundle:Default:AdvertCreate.html.twig');
}
// creation manytomany avec attributs
public function AdvertSkillCreateAction(request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$advert = $em->find("tutoBundle:Advert", $id);
$skills = $em->getRepository("tutoBundle:Skill")->findAll();
foreach ($skills as $key => $skill) {
$advertSkill = new AdvertSkill;
$advertSkill->setAdvert($advert);
$advertSkill->setSkill($skill);
$advertSkill->setLevel("test");
$em->persist($advertSkill);
}
$em->flush();
return $this->redirect($this->generateUrl("Adverts"));
// return new response();
}
} |
view
Code:
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
|
<html>
<body>
<h1> advert </h1>
{% for advert in adverts %}
<table>
<th>Title</th><th>Author</th><th>content</th>
<tr>
<td>{{advert.title}}</td>
<td> <a href="{{ path('AdvertSkillCreate', {'id': advert.id}) }}"/> create skill </a> </td>
</tr>
</table>
{% for skill in advert.advertSkills %}
{{skill.id}} {{skill.skill.name}} <br>
{% endfor %}
{% endfor %} <br>
{#{ladybug_dump(adverts)}}
{{kint()}#}
<a href=" {{ path('AdvertCreate') }} "/> ajouter advert </a><br><br>
</body>
</html> |
et mon problème le repository de advert
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
<?php
namespace test\tutoBundle\Entity;
use Doctrine\ORM\EntityRepository;
class AdvertRepository extends EntityRepository
{
public function getAdvertWithSkill()
{
$qb = $this
->createQueryBuilder('a')
->leftJoin('a.advertSkills', 'advskill')
->addSelect('advskill')
;
return $qb
->getQuery()
->getResult()
;
}
} |
Le problème est le suivant:
via mon repository, j'essaye de joindre la lecture de ma table skill pour avoir le name de chaque.
j'arrive à lire ma table de relation au contraire d'un manytomany classic.
le soucie est qu'il me crée autant de requêtes que de ligne dans ma table skill
ex: j'ai 5 skills donc ainsi il me fait 5 requêtes + 1
Code:
1 2 3 4
|
{% for skill in advert.advertSkills %}
{{skill.id}} {{skill.skill.name}} <br>
{% endfor %} |
comment faire pour joindre mon entity skill en relation avec le foreign key de advertskill en une seul requête car j'ai du mal à la joindre.
je repost le repository
Code:
1 2 3 4 5 6
|
$qb = $this
->createQueryBuilder('a')
->leftJoin('a.advertSkills', 'advskill')
->addSelect('advskill')
; |
Bien à vous,
Gilles Percheron