Symfony4 / Sonata: Create a Many/Many Admin

We will develop here all the manipulations to build a many to many interface via Sonata.
We will take as an example a zone management with a connection by departments. Each zone is thus constituted of multiple connections with the department table.

In MysqlWorkbench, it looks like this:


To generate the entities, we use the following command:

php bin/console doctrine:mapping:import "App\Entity" annotation --path=src/Entity

Next, we create the setters and getters in our entities using the command:

php bin/console make:entity --regenerate App

Now all that's left is to generate our Sonata CRUD without forgetting to clear the cache.

php bin/console make:sonata:admin App/Entity/ZxZone
php bin/console cache:clear

Our interface will be created and the service as well. We will still have to perform a few manipulations.

1 – Remove the ID from our record creation form and add our department field

//ajouter le use suivant
use Symfony\Bridge\Doctrine\Form\Type\EntityType;

//supprimez l'id, et ajouter la liaison département
  protected function configureFormFields(FormMapper $formMapper): void
            ->add('departement', EntityType::class, [
                'class' => 'App\Entity\Departement',
                'choice_label' => 'label',
                'label' => 'Départements',
                'required' => false,
                'by_reference' => false,
                'multiple' => true,
                'expanded' => false,

In the department definition we explicitly ask to display the label field in our list, via the "choice_label" parameter.

This allows us to display a nicer label than just the id. But for this, we must add the following methods in the department entity.

//Permet d'afficher un nom plus sympa dans les messages du CRUD
    public function __toString(): ?string
        return $this->id." : ".$this->nomClairRiche;
//Permet d'afficher un label dans notre liste de configuration
    public function getLabel(): ?string
        return $this->id." : ".$this->nomClairRiche;