简体   繁体   中英

Symfony2 OneToMany embeded form doesn't save entity on

I have persistent problems with OneToMany embedded forms in Symfony2.

This time, the entities are saved, but not the reference to the parent class.

My table looks like that

| id | position | content | about_id |
| 29 |        1 |  test 1 |     NULL |

I cannot understand why this about_id is still NULL.

My relations:

Entity About:

class About {
    /*
     ....
    */

    /**
     * @ORM\OneToMany(targetEntity="AboutContent", mappedBy="about", cascade={"persist", "remove"})
     */
    private $content;

    /**
     * Add content
     *
     * @param AboutContent $content
     * @return About
     */
    public function addContent(AboutContent $content)
    {
        $this->content[] = $content;

        return $this;
    }

    /**
     * Remove content
     *
     * @param AboutContent $content
     */
    public function removeContent(AboutContent $content)
    {
        $this->content->removeElement($content);
    }

    /**
     * Get content
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getContent()
    {
        return $this->content;
    }
}

My About Content:

class AboutContent {
    /**
     * @ORM\ManyToOne(targetEntity="About", inversedBy="content")
     */
    private $about;

    /**
     * Set about
     *
     * @param About $about
     * @return AboutContent
     */
    public function setAbout(About $about = null)
    {
        $this->about = $about;

        return $this;
    }

    /**
     * Get about
     *
     * @return About 
     */
    public function getAbout()
    {
        return $this->about;
    }
}

My controller has been auto generated by my crud:

/**
 * Creates a new About entity.
 *
 */
public function createAction(Request $request)
{
    $entity = new About();
    $form = $this->createCreateForm($entity);
    $form->handleRequest($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();

        $em->persist($entity);
        $em->flush();

        return $this->redirect($this->generateUrl('about_show', array('id' => $entity->getId())));
    }

    return $this->render('AdminBundle:About:new.html.twig', array(
        'entity' => $entity,
        'form'   => $form->createView(),
    ));
}

My form builder:

$builder
  ->add('lang', 'choice', array(
                    'choices'   => $this->langs,
                    'preferred_choices' => array('en'),
        ))            ->add('media')
    ->add('content', 'collection', array(
        'type'         => new AboutContentType(),
        'allow_add'    => true,
        'allow_delete' => true,
        'cascade_validation' => true
      ), array('label'=>'Texts'))       
 ;

 }

Thank you very much if you find the solution.

Hi all after hous of search, I finally find the answer. The problem did not came from my entities or my relation ships. It came from my form.

In my type, I just omitted to add the tag: 'by_reference' => false

It solved everything.

To help you if you have the same problem, below is my builder:

$builder->add(
    'aboutContents',
    'collection',
    [
        'type' => new AboutContentType(),
        'allow_add' => true,
        'allow_delete' => true,
        'cascade_validation' => true,
        'by_reference' => false,
    ],
    [
        'label' => 'Texts'
    ]
);

Your new AboutContent objects don't know about created About entity, because form:
- runs addContent method on About object,
- doesn't run setAbout on AboutContent .

You have to update the association-field on the owning side ( AboutContent ) to persist the relation.

Look at definition of Association Updates .

In your code:
- The owning side is AboutContent entity (because it has the relation to About )
- The inverse side is About entity

So in addContent method you must set About for added AboutContent .

class About {
    //...

    /**
     * Add content
     *
     * @param AboutContent $content
     * @return About
     */
    public function addContent(AboutContent $content)
    {
        $this->content[] = $content;

        $content->setAbout($this); // set the relation on the owning-side

        return $this;
    }

    //...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM