Symfony Doctrine Many to Many insert

2019-07-27 01:07发布

I have a problem with my entities and controllers in Symfony. I would insert on my DB value in a many to many table generated.

Entity Requests with only many to many elements

class Requests {
  /**
 * @ORM\ManyToMany(targetEntity="Tipi", inversedBy="requests")
 * @ORM\JoinTable(name="tipi_richieste")
 */
 private $tipi;


 public function __construct() {
    $this->tipi = new \Doctrine\Common\Collections\ArrayCollection();
 }


 /**
 * Add tipi
 *
 * @param \AppBundle\Entity\Tipi $tipi
 *
 * @return Requests
 */
public function addTipi(\AppBundle\Entity\Tipi $tipi) {
    $this->tipi[] = $tipi;

    return $this;
}

/**
 * Remove tipi
 *
 * @param \AppBundle\Entity\Tipi $tipi
 */
public function removeTipi(\AppBundle\Entity\Tipi $tipi) {
    $this->tipi->removeElement($tipi);
}

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

Entity Tipi with only many to many elements

 class Tipi {
 /**
 * @ORM\ManyToMany(targetEntity="Requests", mappedBy="tipi")
 */
 private $requests;


  /**
 * Constructor
 */
public function __construct() {
    $this->requests = new \Doctrine\Common\Collections\ArrayCollection();
 }

      /**
 * Add request
 *
 * @param \AppBundle\Entity\Requests $request
 *
 * @return Tipi
 */
public function addRequest(\AppBundle\Entity\Requests $request)
{
    $this->requests[] = $request;

    return $this;
}

/**
 * Remove request
 *
 * @param \AppBundle\Entity\Requests $request
 */
public function removeRequest(\AppBundle\Entity\Requests $request)
{
    $this->requests->removeElement($request);
}

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

The Form type for insert is an EntityType

->add('tipi', EntityType::class, array(
                'label' => 'Tipo',
                'class' => 'AppBundle:Tipi',
                'mapped' => false,
                'attr' => array('class' => 'form-control'),
                'multiple'    => true,
                'by_reference' => false,
                'query_builder' => function (EntityRepository $er) {
            return $er->createQueryBuilder('t');
        },
            ))

And in my controller I work in this way:

public function indexAction(Request $request) {

    $requests = new Requests();
    $em = $this->getDoctrine()->getManager();
    $form = $this->createForm(RequestsType::class, $requests);
    $form->handleRequest($request);


    if ($form->isSubmitted() && $form->isValid()) {
        $requests->setCreateAt(new \DateTime('now'));

          $request_tipi = $form["tipi"]->getData();
          $tipi_array = [];
           die($form["tipi"]->getData());
          $tipi_array = $em->getRepository('AppBundle:Tipi')->findOneBy(array('codice' => $form["tipi"]->getData()));
        $tipi = new Tipi();
        $requests->addTipi($form["tipi"]->getData());
        $em->persist($requests);
        $em->flush();

        //return $this->redirectToRoute('immovable_edit', array('id' => $immovables->getId()));
    }
    return $this->render('AppBundle:Requests:index.html.twig', array(
                'requests' => $requests,
                'form' => $form->createView(),
    ));
}

When I put die for return the value of $form["tipi"]->getData() I get an array collection :

Doctrine\Common\Collections\ArrayCollection@000000005b52ae6b00000000731dd0b4

But I get this error

Catchable Fatal Error: Argument 1 passed to AppBundle\Entity\Requests::addTipi() must be an instance of AppBundle\Entity\Tipi, instance of Doctrine\Common\Collections\ArrayCollection given, called in C:\xampp\htdocs\bugaro\src\AppBundle\Controller\RequestsController.php on line 31 and defined

1条回答
男人必须洒脱
2楼-- · 2019-07-27 01:32

Request::addTipi() fuction adds single tipi to its internal collection. Therefore you can't add whole ArrayCollection in call.

You have two options.

Do a foreach

foreach($form["tipi"]->getData() as $tipi) {
    $requests->addTipi($tipi);
}

Create multisetter like Requests::addCollections(ArrayCollection[])

public function addTipis($tipis) {

    foreach($tipis as $tipi) {
        $this->tipi[] = $tipi;
    }

    return $this;
}

Anyway there's a lot to fix in your code. Too much for a single post here.

But the most important of these fixes is that you don't need most of your controller code. ;-)

Since you pass $requests object into the form, it's already bined two-way, which means that Symfony's Form Component should automatically fill it's properties with new values. That includes many to many relation's collections.

Also if you wouldn't pass that object, $form->getData() should return a new Resnponses instance, therefore you don't need to create it and pass manually until it's edition of existing instance.

查看更多
登录 后发表回答