【问题标题】:Symfony3 - Saving a collectionSymfony3 - 保存集合
【发布时间】:2018-06-16 06:30:36
【问题描述】:

我有一个小问题。我有一个对象“角色”,他有几个集合。 我有一个呈现所有集合并允许我添加和删除集合的表单。 之后,我转储了所有信息,并且对象“角色”包含了我在提交表单时发送的所有集合。 当我持久化并刷新数据时,学说会保存角色而不是集合

这是我的配置:

实体角色

/**
 * @ORM\OneToMany(targetEntity="PersonaDomicilio",mappedBy="idPersona",cascade={"persist"},orphanRemoval=true)
 */
private $domicilios;

public function __construct() {
    $this->domicilios = new ArrayCollection();
}

public function getDomicilios() {
    return $this->domicilios;
}

public function addDomicilio(PersonaDomicilio $persona_domicilio) {
    $persona_domicilio->setIdPersona($this);
    $this->domicilios[] = $persona_domicilio;
}

public function removeDomicilio(PersonaDomicilio $persona_domicilio) {
    $this->domicilios->removeElement($persona_domicilio);
}

Entity PersonaDomicilio

/**
 * @var \AppBundle\Entity\Persona
 *
 * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Persona",inversedBy="domicilios")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="id_persona", referencedColumnName="id_persona")
 * })
 */
private $idPersona;

角色类型

->add('domicilios', CollectionType::class, array(
                'entry_type' => PersonaDomicilioType::class,
                'allow_add' => true,
                'allow_delete' => true,
                'by_reference' => false,
                'label' => false

            ))

控制器动作

$em = $this->getDoctrine()->getManager();
    $persona = new Persona();
    $formulario = $this->createForm(
        PersonaType::class, 
       $persona,
        array('action' => $this->generateUrl('persona_create'),
              'method' => 'POST')
    );

    $formulario->handleRequest($request);

    $persona->setFisicaJuridica('F');
    $em->persist($persona);
    $em->flush();

我不想使用 foreach 手动持久化所有集合,因为级联持久化将有助于做到这一点。 我不得不说我做了几次测试,但我不明白为什么不起作用。

Pd:“id_persona”也正确设置为集合。

【问题讨论】:

    标签: symfony collections persist


    【解决方案1】:

    这是“正常的”。如果你引用这个old symfony documentation(它仍然有效),你还必须持久化你的 PersonaDomicilio(参见 Doctrine: Ensuring the database persistence)。

    这是他们的例子:

    // src/Acme/TaskBundle/Controller/TaskController.php
    
    use Doctrine\Common\Collections\ArrayCollection;
    
    // ...
    public function editAction($id, Request $request)
    {
        $em = $this->getDoctrine()->getManager();
        $task = $em->getRepository('AcmeTaskBundle:Task')->find($id);
    
        if (!$task) {
            throw $this->createNotFoundException('No task found for id '.$id);
        }
    
        $originalTags = new ArrayCollection();
    
        // Create an ArrayCollection of the current Tag objects in the database
        foreach ($task->getTags() as $tag) {
            $originalTags->add($tag);
        }
    
        $editForm = $this->createForm(new TaskType(), $task);
    
        $editForm->handleRequest($request);
    
        if ($editForm->isValid()) {
    
            // remove the relationship between the tag and the Task
            foreach ($originalTags as $tag) {
                if (false === $task->getTags()->contains($tag)) {
                    // remove the Task from the Tag
                    $tag->getTasks()->removeElement($task);
    
                    // if it was a many-to-one relationship, remove the relationship like this
                    // $tag->setTask(null);
    
                    $em->persist($tag);
    
                    // if you wanted to delete the Tag entirely, you can also do that
                    // $em->remove($tag);
                }
            }
    
            $em->persist($task);
            $em->flush();
    
            // redirect back to some edit page
            return $this->redirectToRoute('task_edit', array('id' => $id));
        }
    
        // render some form template
    }
    

    这里是您的配置示例(未测试)

    <?php
    
    // Create an ArrayCollection of the current domicilios objects in the database
    $originalDomicilios = new ArrayCollection();
    foreach ($persona->getDomicilios() as $domicilio) {
        $originalDomicilios->add($domicilio);
    }
    
    // Check request
    $form->handleRequest($request);
    
    // Was the form submitted?
    if ($form->isSubmitted() && $form->isValid()) {
        try {
    
            // Handle domicilios
            foreach ($originalDomicilios as $domicilio) {
                if (false === $persona->getDomicilios()->contains($domicilio)) {
    
                    // remove the persona from the domicilio (or remove it)
                    $domicilio->removePersona($persona);
    
                    // Persist domicilio
                    $em->persist($domicilio);
                }
            }
    
            // Save new domicilios
            foreach($persona->getDomicilios() as $domicilio){
                if (false === $originalDomicilios->contains($domicilio)){
    
                    // Add persona
                    $domicilio->addPersona($persona);
    
                    // Persist domicilio
                    $em->persist($domicilio);
                }
            }
    
            // Persist persona
            $em->persist($persona);
    
            // Save
            $em->flush();
    
            ...
    
        } catch (\Exception $e) {
    
    
        }
    }
    

    【讨论】:

    • 是的,但它是一个编辑操作,我在那里有一个新操作,默认情况下集合将通过级联持久化进行持久化
    • 我也有这些集合,但没有在我的示例中添加它们。
    • 我只需要保存它们
    • 级联持久化还不够。您必须坚持两种大小的关系(它适用于添加或编辑操作)
    • 所以,在这两种情况下以及所有操作中,我都必须手动坚持,不是吗?
    猜你喜欢
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    相关资源
    最近更新 更多