2

I would like to create a ManyToMany relationship with Symfony3/doctrine (The entities are 'Categorie' and 'Service')

So I have two forms to create this entites.

The first form (Categorie) works properly but not the second (Service) : The new service is not related to categories, i don't understand :

Categorie.php

/**
 * Categorie
 *
 * @ORM\Table(name="categorie")
 * @ORM\Entity(repositoryClass="GestionBundle\Repository\CategorieRepository")
 */
class Categorie 
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToMany(targetEntity="Service", inversedBy="categories")
     */
    private $services;

    /**
     * Categorie constructor.
     */
    public function __construct()
    {
        $this->services = new ArrayCollection();
    }

    [...]
}

Service.php

/**
 * Service
 *
 * @ORM\Table(name="service")
 * @ORM\Entity(repositoryClass="GestionBundle\Repository\ServiceRepository")
 */
class Service
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToMany(targetEntity="Categorie", mappedBy="services")
     */
    private $categories;

    /**
     * @var string
     *
     * @ORM\Column(name="nom", type="string", length=255, unique=true)
     */
    private $nom;

    /**
     * Categorie constructor.
     */
    public function __construct()
    {
        $this->categories = new ArrayCollection();
    }

    [...]
}

CategorieType.php

class CategorieType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('nom')
            ->add('services', EntityType::class, array(
                'class'        => 'GestionBundle:Service',
                'choice_label' => 'nom',
                'multiple'     => true,
                'required'     => false))
            ->add('Ajouter', SubmitType::class)
        ;
    }

    [...]
}

ServiceType.php

class ServiceType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('nom')
            ->add('categories', EntityType::class, array(
                'class'        => 'GestionBundle:Categorie',
                'choice_label' => 'nom',
                'multiple'     => true,
                'required'     => false))
            ->add('Ajouter', SubmitType::class)
        ;
    }

    [...]
}

Controller :

/**
     * @Route("/Categories/Creation", name="route_gestion_eltcoord_categories_creation")
     * @Template()
     */
    public function CreationCategorieAction(Request $request)
    {
        $Categorie = new Categorie();

        $form = $this->createForm(CategorieType::class, $Categorie);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($Categorie);
            $em->flush();
            return $this->redirectToRoute('route_gestion_eltcoord_categories');
        }

        return array('form' => $form->createView());
    }

/**
     * @Route("/Services/Creation", name="route_gestion_eltcoord_services_creation")
     * @Template()
     */
    public function CreationServiceAction(Request $request)
    {
        $Service = new Service();

        $form = $this->createForm(ServiceType::class, $Service);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($Service);
            $em->flush();
            return $this->redirectToRoute('route_gestion_eltcoord_services');
        }

        return array('form' => $form->createView());
    }

Thank you.

Jean-Luc Barat
  • 1,147
  • 10
  • 18
Cliffe
  • 107
  • 1
  • 9

4 Answers4

0

As I understand you wan't nested form from category root form ?

Try CollectionType::class instead of EntityType::class in service form builder, configure options (at less entry_type to map entity class).

Related documentation for configuration here.

And here there is example from Symfony cookbook.

Jean-Luc Barat
  • 1,147
  • 10
  • 18
0

In a ManyToMany relations you must create a joined table like in this post, so in that way doctrine can create a third entity for describe the relation.

Hope this help you.

Community
  • 1
  • 1
abdiel
  • 2,078
  • 16
  • 24
0

I already have the joined table.

Here is an example :

  1. New 'Service' S1 (Form Service) :
     Service          Categorie        categorie_service
+------+-------+   +------+-------+   +--------+--------+
|  id  |  Name |   |  id  |  Name |   |  id_c  |  id_s  |
+------+-------+   +------+-------+   +--------+--------+
|   1  |   S1  | 
+------+-------+
  1. New 'Categorie' C1 related to S1 (Form Categorie) :
     Service          Categorie        categorie_service
+------+-------+   +------+-------+   +--------+--------+
|  id  |  Name |   |  id  |  Name |   |  id_c  |  id_s  |
+------+-------+   +------+-------+   +--------+--------+
|   1  |   S1  |   |   1  |   C1  |   |    1   |    1   |
+------+-------+   +------+-------+   +--------+--------+
  1. New 'Service' S2 related to C1 (Form Service) :
     Service          Categorie        categorie_service
+------+-------+   +------+-------+   +--------+--------+
|  id  |  Name |   |  id  |  Name |   |  id_c  |  id_s  |
+------+-------+   +------+-------+   +--------+--------+
|   1  |   S1  |   |   1  |   C1  |   |    1   |    1   |
+------+-------+   +------+-------+   +--------+--------+
|   2  |   S2  |
+------+-------+

doesn't work ...

I should have this:

 categorie_service
+--------+--------+
|  id_c  |  id_s  |
+--------+--------+
|    1   |    1   |
+--------+--------+
|    1   |    2   |
+--------+--------+

;p

Cliffe
  • 107
  • 1
  • 9
0

I added this :

$categories = $form->getData()->getCategories(); 
foreach ($categories as $categorie) {
    $categorie->addService($service);
}

into 'CreationServiceAction' and before call $em->persist...

Now it's ok.

Cliffe
  • 107
  • 1
  • 9