Symfony2 Много к одному - один ко многим без таблицы соединений
У меня есть объект "Проект", который может иметь несколько преимуществ, в то время как выгода принадлежит только одному проекту: мне кажется, что отношения один ко многим - один ко многим. Я следовал указаниям здесь
Объект проекта:
/**
* @ORM\Entity(repositoryClass="AppBundle\Entity\ProjectRepository")
* @ORM\Table(name="projects")
*/
class Project
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\oneToMany(targetEntity="Benefit", mappedBy="project")
*/
protected $benefits;
/**
* Constructor
*/
public function __construct()
{
$this->benefits = new \Doctrine\Common\Collections\ArrayCollection();
}
// other stuff
/**
* Add benefits
*
* @param \AppBundle\Entity\Benefit $benefits
* @return Project
*/
public function addBenefit(\AppBundle\Entity\Benefit $benefits)
{
$this->benefits[] = $benefits;
return $this;
}
/**
* Remove benefits
*
* @param \AppBundle\Entity\Benefit $benefits
*/
public function removeBenefit(\AppBundle\Entity\Benefit $benefits)
{
$this->benefits->removeElement($benefits);
}
/**
* Get benefits
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getBenefits()
{
return $this->benefits;
}
}
Выгода является:
/**
* @ORM\Entity(repositoryClass="AppBundle\Entity\BenefitRepository")
* @ORM\Table(name="benefits")
*/
class Benefit
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
// Other relevant fields
/**
* @ORM\ManyToOne(targetEntity="Project", inversedBy="benefits")
*/
protected $project;
В моем контроллере я надеялся сделать:
$project = $em->getRepository('AppBundle:Project')->findOneById(3);
$benefit = new Benefit();
// set some fields for the new Benefit
$benefit->setProject($project);
$em->persist($benefit);
и я надеялся увидеть преимущества как совокупность внутри объекта проекта:
$benefits = $project->getBenefits();
Но это не сработало, поэтому я явно сделал:
$project->addBenefit($benefit);
$em->persist($project);
$benefits = $project->getBenefits();
И я действительно вижу новый недавно созданный Бенефит внутри проекта коллекции внутри. Проблема в том, что, если я повторно запишу это и добавлю новое преимущество к тому же проекту, я просто получу последнее. Конечно, если в одной и той же части кода я создаю 2 преимущества и добавляю оба, у меня есть набор из 2, но это не то, что я хочу. Со стороны Преимущества все в порядке: каждое новое Преимущество сохраняется, и все они правильно указывают на один и тот же Проект.
Что мне не хватает?
РЕДАКТИРОВАТЬ:
Вот шаги, которые я делаю / вещи, которые я проверял:
БД синхронизируется с метаданными текущего объекта. Обновленная сущность проекта:
<?php
// src/AppBundle/Entity/Project.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="AppBundle\Entity\ProjectRepository")
* @ORM\Table(name="projects")
*/
class Project
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\oneToMany(targetEntity="Benefit", mappedBy="project", cascade="persist")
*/
protected $benefits;
/**
* Constructor
*/
public function __construct()
{
$this->benefits = new \Doctrine\Common\Collections\ArrayCollection();
}
// Other irrelevant fields
/**
* Add benefits
*
* @param \AppBundle\Entity\Benefit $benefit
* @return Project
*/
public function addBenefit(\AppBundle\Entity\Benefit $benefit)
{
$this->benefits[] = $benefit;
$benefit->setProject($this);
return $this;
}
/**
* Remove benefits
*
* @param \AppBundle\Entity\Benefit $benefits
*/
public function removeBenefit(\AppBundle\Entity\Benefit $benefits)
{
$this->benefits->removeElement($benefits);
}
/**
* Get benefits
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getBenefits()
{
return $this->benefits;
}
}
Обратите внимание, что remove Benefit, вероятно, не реализован должным образом, но на данный момент это не актуально.
Я чищу таблицу преимуществ.
Я создаю новое преимущество и прикрепляю к проекту:
$em = $this->getDoctrine()->getManager();
$project = $em->getRepository('AppBundle:Project')->findOneById(3);
$benefit = new Benefit();
$benefit->setName('Name of the benefit');
// here I set other irrelevant fields
$project->addBenefit($benefit);
$em->persist($project);
$em->flush();
Преимущество должным образом сохраняется в БД. Это правильно ссылки на проект:
Затем я комментирую весь код в контроллере и просто выполняю:
$em = $this->getDoctrine()->getManager();
$project = $em->getRepository('AppBundle:Project')->findOneById(3);
$benefits = $project->getBenefits();
return $this->render('testBenefits.html.twig', array(
'benefits' => $benefits, 'project' => $project));
Если я сбрасываю $project, я получаю:
И, конечно, если я сбрасываю $ выгоды, я получаю это:
1 ответ
Вы не устанавливаете проект в своем классе выгоды.
public function addBenefit(\AppBundle\Entity\Benefit $benefit)
{
$this->benefits[] = $benefit;
$benefit->setProject($this); // Add this
return $this;
}
Заметил, что я также изменил ваш аргумент от преимуществ к выгоде, так как addBenefit работает с одним объектом выгоды за раз.