#php #symfony #doctrine-orm #doctrine #many-to-many
Вопрос:
Я начал создавать базу данных, используя множество связей с доктриной. Я переключился на другой подход, потому что мне нужны были дополнительные поля в таблице ассоциаций. Я использую symfony 5
Я имею в виду 3 Сущности:
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
, в котором я могу определить более 1 раздела, который будет использоваться в этом шаблоне. В secInput-это разделенный запятыми список значений(идентификаторов), которые будут использоваться для выбранных разделов.
Когда я пытаюсь сохранить форму, только последняя запись сохраняется в Template.sections
Что мне нужно изменить, чтобы сохранить все данные в базе данных?
Мой код в TemplateController:
/** * @Route("/new", name="adminTemplateNew", methods={"GET","POST"}) */ public function new(Request $request): Response { $template = new Template(); $form = $this-gt;createForm(TemplateType::class, $template); $form-gt;handleRequest($request); if ($form-gt;isSubmitted() amp;amp; $form-gt;isValid()) { $entityManager = $this-gt;getDoctrine()-gt;getManager(); $data = $form-gt;getData(); $repo = $entityManager-gt;getRepository(Section::class); $templateSection = new TemplateSection(); $template-gt;setCreatedAt(new DateTime('NOW')); $sections = explode(',', $form-gt;get('secInput')-gt;getData()); $count = 1; foreach ($sections as $secId) { if ( null !== $section = $repo-gt;find($secId) ) { $templateSection-gt;setSortOrder($count); $templateSection-gt;setTemplate($template); $templateSection-gt;setSection($section); $template-gt;addSection($templateSection); $entityManager-gt;persist($templateSection); $count ; } } $entityManager-gt;persist($templateSection); $entityManager-gt;persist($template); $entityManager-gt;flush(); return $this-gt;redirectToRoute('template_index', ['data' =gt; $data], Response::HTTP_SEE_OTHER); }
Ответ №1:
Вы повторяете выбранные разделы и перезаписываете их без сохранения. Когда вы звоните $entityManager-gt;persist($templateSection)
, вы указываете EntityManager отслеживать его, но в конце концов, когда вы звоните $entityManager-gt;flush()
, сохраняется только один объект. И это происходит с самыми последними данными.
Попробуйте создать новый объект и сохранить его, вот так:
public function new(Request $request): Response { $form = $this-gt;createForm(TemplateType::class, $template); $form-gt;handleRequest($request); if ($form-gt;isSubmitted() amp;amp; $form-gt;isValid()) { $entityManager = $this-gt;getDoctrine()-gt;getManager(); $data = $form-gt;getData(); $repo = $entityManager-gt;getRepository(Section::class); $template = new Template(); $template-gt;setCreatedAt(new DateTime('NOW')); $sections = explode(',', $form-gt;get('secInput')-gt;getData()); $count = 1; foreach ($sections as $secId) { if ( null !== $section = $repo-gt;find($secId) ) { $templateSection = new TemplateSection(); // This is new $templateSection-gt;setSortOrder($count); $templateSection-gt;setTemplate($template); $templateSection-gt;setSection($section); $template-gt;addSection($templateSection); $entityManager-gt;persist($templateSection); $count ; } } $entityManager-gt;persist($template); $entityManager-gt;flush(); return $this-gt;redirectToRoute('template_index', ['data' =gt; $data], Response::HTTP_SEE_OTHER); }
Комментарии:
1. Так верно и очевидно, Что я был слеп по своему собственному кодексу. Отлично работает, большое спасибо!