Doctrine - 将 ManyToMany 与其他字段一起使用,并希望在关联中保存多行 table
Doctrine - using ManyToMany with additional fields and want to save more than one row in association table
我开始使用 ManyToMany 关系与学说建立数据库。
我切换到另一种方法,因为我需要关联中的其他字段 table。
我正在使用 symfony 5
我拥有 3 个实体:
namespace App\Entity;
use App\Repository\TemplateRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=TemplateRepository::class)
* @ORM\Table(options={"collate"="utf8mb4_general_ci"})
*/
class Template
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\OneToMany(targetEntity=TemplateSection::class, mappedBy="section", cascade={"persist"})
*/
private $sections;
....
}
namespace App\Entity;
use App\Repository\SectionRepository;
use App\DBAL\Types\SectionElementType;
use Doctrine\ORM\Mapping as ORM;
use Fresh\DoctrineEnumBundle\Validator\Constraints as DoctrineAssert;
/**
* @ORM\Entity(repositoryClass=SectionRepository::class)
* @ORM\Table(options={"collate"="utf8mb4_general_ci"})
*/
class Section
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\OneToMany(targetEntity=TemplateSection::class, mappedBy="template")
*/
private $template;
/**
* @ORM\Column(type="string", length=255)
*/
private $title;
....
}
namespace App\Entity;
use App\Repository\TemplateSectionRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=TemplateSectionRepository::class)
* @ORM\Table(options={"collate"="utf8mb4_general_ci"})
*/
class TemplateSection
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity=Template::class, inversedBy="id", cascade={"persist"})
* @ORM\JoinColumn(nullable=false)
*/
private $template;
/**
* @ORM\ManyToOne(targetEntity=Section::class, inversedBy="id", cascade={"persist"})
* @ORM\JoinColumn(nullable=false)
*/
private $section;
/**
* @ORM\Column(type="smallint", options={"default": "0"})
*/
private $sortOrder;
....
}
我有一个可以为模板定义新条目的表单。有一个字段 secInput
,我可以在其中定义超过 1 个部分以用于此模板。
在 secInput 中是用于所选部分的逗号分隔值列表 (Id)。
当我尝试保存表格时,只有最后一条记录保存在 Template.sections
我必须更改什么才能将所有给定数据保存到数据库?
我在 TemplateController 中的代码:
/**
* @Route("/new", name="adminTemplateNew", methods={"GET","POST"})
*/
public function new(Request $request): Response
{
$template = new Template();
$form = $this->createForm(TemplateType::class, $template);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$data = $form->getData();
$repo = $entityManager->getRepository(Section::class);
$templateSection = new TemplateSection();
$template->setCreatedAt(new DateTime('NOW'));
$sections = explode(',', $form->get('secInput')->getData());
$count = 1;
foreach ($sections as $secId) {
if ( null !== $section = $repo->find($secId) ) {
$templateSection->setSortOrder($count);
$templateSection->setTemplate($template);
$templateSection->setSection($section);
$template->addSection($templateSection);
$entityManager->persist($templateSection);
$count++;
}
}
$entityManager->persist($templateSection);
$entityManager->persist($template);
$entityManager->flush();
return $this->redirectToRoute('template_index', ['data' => $data], Response::HTTP_SEE_OTHER);
}
您正在遍历所选部分并在不保存的情况下覆盖它们。当您调用 $entityManager->persist($templateSection)
时,您告诉 EntityManager 对其进行跟踪,但最终,当您调用 $entityManager->flush()
时,只会保留一个对象。而且恰好是最新的数据。
尝试构建一个新对象并将其持久化,如下所示:
public function new(Request $request): Response
{
$form = $this->createForm(TemplateType::class, $template);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$data = $form->getData();
$repo = $entityManager->getRepository(Section::class);
$template = new Template();
$template->setCreatedAt(new DateTime('NOW'));
$sections = explode(',', $form->get('secInput')->getData());
$count = 1;
foreach ($sections as $secId) {
if ( null !== $section = $repo->find($secId) ) {
$templateSection = new TemplateSection(); // This is new
$templateSection->setSortOrder($count);
$templateSection->setTemplate($template);
$templateSection->setSection($section);
$template->addSection($templateSection);
$entityManager->persist($templateSection);
$count++;
}
}
$entityManager->persist($template);
$entityManager->flush();
return $this->redirectToRoute('template_index', ['data' => $data], Response::HTTP_SEE_OTHER);
}
我开始使用 ManyToMany 关系与学说建立数据库。 我切换到另一种方法,因为我需要关联中的其他字段 table。 我正在使用 symfony 5
我拥有 3 个实体:
namespace App\Entity;
use App\Repository\TemplateRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=TemplateRepository::class)
* @ORM\Table(options={"collate"="utf8mb4_general_ci"})
*/
class Template
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\OneToMany(targetEntity=TemplateSection::class, mappedBy="section", cascade={"persist"})
*/
private $sections;
....
}
namespace App\Entity;
use App\Repository\SectionRepository;
use App\DBAL\Types\SectionElementType;
use Doctrine\ORM\Mapping as ORM;
use Fresh\DoctrineEnumBundle\Validator\Constraints as DoctrineAssert;
/**
* @ORM\Entity(repositoryClass=SectionRepository::class)
* @ORM\Table(options={"collate"="utf8mb4_general_ci"})
*/
class Section
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\OneToMany(targetEntity=TemplateSection::class, mappedBy="template")
*/
private $template;
/**
* @ORM\Column(type="string", length=255)
*/
private $title;
....
}
namespace App\Entity;
use App\Repository\TemplateSectionRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=TemplateSectionRepository::class)
* @ORM\Table(options={"collate"="utf8mb4_general_ci"})
*/
class TemplateSection
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity=Template::class, inversedBy="id", cascade={"persist"})
* @ORM\JoinColumn(nullable=false)
*/
private $template;
/**
* @ORM\ManyToOne(targetEntity=Section::class, inversedBy="id", cascade={"persist"})
* @ORM\JoinColumn(nullable=false)
*/
private $section;
/**
* @ORM\Column(type="smallint", options={"default": "0"})
*/
private $sortOrder;
....
}
我有一个可以为模板定义新条目的表单。有一个字段 secInput
,我可以在其中定义超过 1 个部分以用于此模板。
在 secInput 中是用于所选部分的逗号分隔值列表 (Id)。
当我尝试保存表格时,只有最后一条记录保存在 Template.sections
我必须更改什么才能将所有给定数据保存到数据库?
我在 TemplateController 中的代码:
/**
* @Route("/new", name="adminTemplateNew", methods={"GET","POST"})
*/
public function new(Request $request): Response
{
$template = new Template();
$form = $this->createForm(TemplateType::class, $template);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$data = $form->getData();
$repo = $entityManager->getRepository(Section::class);
$templateSection = new TemplateSection();
$template->setCreatedAt(new DateTime('NOW'));
$sections = explode(',', $form->get('secInput')->getData());
$count = 1;
foreach ($sections as $secId) {
if ( null !== $section = $repo->find($secId) ) {
$templateSection->setSortOrder($count);
$templateSection->setTemplate($template);
$templateSection->setSection($section);
$template->addSection($templateSection);
$entityManager->persist($templateSection);
$count++;
}
}
$entityManager->persist($templateSection);
$entityManager->persist($template);
$entityManager->flush();
return $this->redirectToRoute('template_index', ['data' => $data], Response::HTTP_SEE_OTHER);
}
您正在遍历所选部分并在不保存的情况下覆盖它们。当您调用 $entityManager->persist($templateSection)
时,您告诉 EntityManager 对其进行跟踪,但最终,当您调用 $entityManager->flush()
时,只会保留一个对象。而且恰好是最新的数据。
尝试构建一个新对象并将其持久化,如下所示:
public function new(Request $request): Response
{
$form = $this->createForm(TemplateType::class, $template);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$data = $form->getData();
$repo = $entityManager->getRepository(Section::class);
$template = new Template();
$template->setCreatedAt(new DateTime('NOW'));
$sections = explode(',', $form->get('secInput')->getData());
$count = 1;
foreach ($sections as $secId) {
if ( null !== $section = $repo->find($secId) ) {
$templateSection = new TemplateSection(); // This is new
$templateSection->setSortOrder($count);
$templateSection->setTemplate($template);
$templateSection->setSection($section);
$template->addSection($templateSection);
$entityManager->persist($templateSection);
$count++;
}
}
$entityManager->persist($template);
$entityManager->flush();
return $this->redirectToRoute('template_index', ['data' => $data], Response::HTTP_SEE_OTHER);
}