I get it. Hope this post can help others who were just as frustrated as I am!
path.php
<?php namespace JStout\MainBundle\Entity; use Doctrine\ORM\Mapping as ORM; class Path { private $id; private $offers; [...]
PathOffer.php
<?php namespace JStout\MainBundle\Entity; use Doctrine\ORM\Mapping as ORM; class PathOffer { private $id; private $path; private $offer; private $pos; [...]
Offer.php
<?php namespace JStout\MainBundle\Entity; use Doctrine\ORM\Mapping as ORM; class Offer { private $id; private $paths; [...]
And for my interface logic:
Pathcontroller.php
<?php [...] /** * @Extra\Route("/path", name="admin_path") * @Extra\Route("/path/{id}/edit", name="admin_path_edit", requirements={"id" = "\d+"}) * @Extra\Template() */ public function pathAction($id = null) { $path = $this->_getObject('Path', $id); // this function either generates a new entity or grabs one from database depending on $id $form = $this->get('form.factory')->create(new Form\PathType(), $path); $formHandler = $this->get('form.handler')->create(new Form\PathHandler(), $form); // process form if ($formHandler->process()) { $this->get('session')->setFlash('notice', 'Successfully ' . ($this->_isEdit($path) ? 'edited' : 'added') . ' path!'); return $this->redirect($this->generateUrl('admin_path')); } return array( 'path' => $path, 'form' => $form->createView(), 'postUrl' => !$this->_isEdit($path) ? $this->generateUrl('admin_path') : $this->generateUrl('admin_path_edit', array('id' => $path->getId())), 'paths' => $this->_paginate('Path'), 'edit' => $this->_isEdit($path) ? true : false ); } [...]
PathType.php (path form)
<?php namespace JStout\MainBundle\Form; use Symfony\Component\Form\AbstractType, Symfony\Component\Form\FormBuilder; class PathType extends AbstractType { public function buildForm(FormBuilder $builder, array $options) { $builder ->add('name') ->add('title') ->add('offers', 'collection', array( 'type' => new PathOfferType(), 'allow_add' => true, 'allow_delete' => true )) ->add('active'); } public function getDefaultOptions(array $options) { return array( 'data_class' => 'JStout\MainBundle\Entity\Path' ); } }
PathOfferType.php (PathType offers a collection type)
<?php namespace JStout\MainBundle\Form; use Symfony\Component\Form\AbstractType, Symfony\Component\Form\FormBuilder; class PathOfferType extends AbstractType { public function buildForm(FormBuilder $builder, array $options) { $builder ->add('offer', 'entity', array( 'class' => 'JStout\MainBundle\Entity\Offer', 'query_builder' => function($repository) { return $repository->createQueryBuilder('o')->orderBy('o.name', 'ASC'); }, 'property' => 'name' )) ->add('pos', 'integer'); } public function getDefaultOptions(array $options) { return array( 'data_class' => 'JStout\MainBundle\Entity\PathOffer' ); } }
PathHandler.php (how I handle the form)
<?php namespace JStout\MainBundle\Form; use JStout\MainBundle\Component\Form\FormHandlerInterface, Symfony\Component\Form\Form, Symfony\Component\HttpFoundation\Request, Doctrine\ORM\EntityManager, JStout\MainBundle\Entity\Path; class PathHandler implements FormHandlerInterface { protected $form; protected $request; protected $entityManager; public function buildFormHandler(Form $form, Request $request, EntityManager $entityManager) { $this->form = $form; $this->request = $request; $this->entityManager = $entityManager; } public function process() { if ('POST' == $this->request->getMethod()) {