原则-使用带有附加字段的manymany,并希望在关联表中保存多行



我开始用多对多关系建立数据库。我切换到另一种方法,因为我需要在关联表中添加其他字段。我用symfony 5

我有三个实体:

namespace AppEntity;
use AppRepositoryTemplateRepository;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
/**
* @ORMEntity(repositoryClass=TemplateRepository::class)
* @ORMTable(options={"collate"="utf8mb4_general_ci"})
*/
class Template
{
/**
* @ORMId
* @ORMGeneratedValue
* @ORMColumn(type="integer")
*/
private $id;
/**
* @ORMOneToMany(targetEntity=TemplateSection::class, mappedBy="section", cascade={"persist"})
*/
private $sections;
....
}

namespace AppEntity;
use AppRepositorySectionRepository;
use AppDBALTypesSectionElementType;
use DoctrineORMMapping as ORM;
use FreshDoctrineEnumBundleValidatorConstraints as DoctrineAssert;
/**
* @ORMEntity(repositoryClass=SectionRepository::class)
* @ORMTable(options={"collate"="utf8mb4_general_ci"})
*/
class Section
{
/**
* @ORMId
* @ORMGeneratedValue
* @ORMColumn(type="integer")
*/
private $id;
/**
* @ORMOneToMany(targetEntity=TemplateSection::class, mappedBy="template")
*/
private $template;
/**
* @ORMColumn(type="string", length=255)
*/
private $title;
....
}

namespace AppEntity;
use AppRepositoryTemplateSectionRepository;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
/**
* @ORMEntity(repositoryClass=TemplateSectionRepository::class)
* @ORMTable(options={"collate"="utf8mb4_general_ci"})
*/
class TemplateSection
{
/**
* @ORMId
* @ORMGeneratedValue
* @ORMColumn(type="integer")
*/
private $id;
/**
* @ORMManyToOne(targetEntity=Template::class, inversedBy="id", cascade={"persist"})
* @ORMJoinColumn(nullable=false)
*/
private $template;
/**
* @ORMManyToOne(targetEntity=Section::class, inversedBy="id", cascade={"persist"})
* @ORMJoinColumn(nullable=false)
*/
private $section;
/**
* @ORMColumn(type="smallint", options={"default": "0"})
*/
private $sortOrder;
....
}

我有一个表单,我可以为模板定义新的条目。有一个字段secInput,我可以在其中定义多个要在此模板中使用的部分。在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);
}

最新更新