Home > Software engineering >  Problem with my entity and type Symfony 6
Problem with my entity and type Symfony 6

Time:01-19

first of all, soory for my English, I'm French.

So, I try to create a form that use many entities. Here they are :

Controller :

class  SaisieController extends AbstractController
{
    #[Route('/user/saisie', name: 'app_usersaisie')]
    public function add(Request $request, ManagerRegistry $doctrine, EntityManagerInterface $entityManager,): Response
    {
        $session = new ChasseurAnimauxSession();
        $form = $this->createForm(SaisieFormType::class, $session);

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {//
            $em = $entityManager;
            $em->persist($form->getData());
            $em->flush();

            return $this->render('user/informationsUser.html.twig', [
                'form_index' => $form->createView(),
            ]);
        }
        return $this->render('user/informationsUser.html.twig', [
            'form_index' => $form->createView(),
        ]);
    }
}

First Entity ChasseurAniamauxSession :

    namespace App\Entity;

use App\Repository\ChasseurAnimauxSessionRepository;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: ChasseurAnimauxSessionRepository::class)]
class ChasseurAnimauxSession
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 10, nullable: true)]
    private ?string $sexe = null;

    #[ORM\Column(nullable: true)]
    private ?int $poids = null;

    #[ORM\OneToMany(mappedBy: 'id', targetEntity: SessionChasse::class)]
    #[ORM\Column(nullable: true)]
    private ?int $session_chasse_id = null;

    #[ORM\OneToMany(mappedBy: 'id', targetEntity: Animaux::class)]
    #[ORM\Column(nullable: true)]
    private ?int $animaux_id = null;

    #[ORM\OneToMany(mappedBy: 'id', targetEntity: User::class)]
    #[ORM\Column(nullable: true)]
    private ?int $chasseur_id = null;

    #[ORM\Column(nullable: true)]
    private ?int $number_bague = null;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getSexe(): ?string
    {
        return $this->sexe;
    }

    public function setSexe(?string $sexe): self
    {
        $this->sexe = $sexe;

        return $this;
    }

    public function getPoids(): ?int
    {
        return $this->poids;
    }

    public function setPoids(?int $poids): self
    {
        $this->poids = $poids;

        return $this;
    }

    /**
     * @return int|null
     */
    public function getSessionChasseId(): ?int
    {
        return $this->session_chasse_id;
    }

    /**
     * @param int|null $session_chasse_id
     * @return ChasseurAnimauxSession
     */
    public function setSessionChasseId(?int $session_chasse_id): ChasseurAnimauxSession
    {
        $this->session_chasse_id = $session_chasse_id;
        return $this;
    }

    /**
     * @return int|null
     */
    public function getAnimauxId(): ?int
    {
        return $this->animaux_id;
    }

    /**
     * @param int|null $animaux_id
     * @return ChasseurAnimauxSession
     */
    public function setAnimauxId(?int $animaux_id): ChasseurAnimauxSession
    {
        $this->animaux_id = $animaux_id;
        return $this;
    }

    /**
     * @return int|null
     */
    public function getChasseurId(): ?int
    {
        return $this->chasseur_id;
    }

    /**
     * @param int|null $chasseur_id
     * @return ChasseurAnimauxSession
     */
    public function setChasseurId(?int $chasseur_id): ChasseurAnimauxSession
    {
        $this->chasseur_id = $chasseur_id;
        return $this;
    }



    public function getNumberBague(): ?int
    {
        return $this->number_bague;
    }

    public function setNumberBague(?int $number_bague): self
    {
        $this->number_bague = $number_bague;

        return $this;
    }
}

Another Entity Animaux :

namespace App\Entity;

use App\Repository\AnimauxRepository;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: AnimauxRepository::class)]
class Animaux
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 255, nullable: true)]
    private ?string $espece = null;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getEspece(): ?string
    {
        return $this->espece;
    }

    public function setEspece(?string $espece): self
    {
        $this->espece = $espece;

        return $this;
    }
}

The type :

<?php

namespace App\Form\user;

use App\Entity\Animaux;
use App\Entity\SessionChasse;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;

class SaisieFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('animaux_id', EntityType::class,
                ['class' => Animaux::class,
                    'choice_label' => 'id'])
            ->add('session_chasse_id', EntityType::class,
                ['class' => SessionChasse::class,])
            ->add('number_bague', IntegerType::class,
                ['label' => 'Numéro de bague'])
            ->add('sexe', TextType::class,)
            ->add('poids', IntegerType::class,)
            ->add('save', SubmitType::class,
                ['label' => 'Enregistrer']);
    }
}

I don't give you the another entity because I think if the answer for this one will help to solve the problem with the others. If you need more informations, tell me.

The error that I have is this one :

Expected argument of type "?int", "App\Entity\Animaux" given at property path "animaux_id".

I think it's basic error, but I spend hours on the symfony doc and forums and I don't make any progress.

Thank you for you help.

edit: I add the OneToMany that I forgot at the beginning.

CodePudding user response:

It looks like you do it in the MERISE way, a french method (IMO a good method). As far as I understood, a SessionChasseurAnimaux is connected to one Animal as you were linking to one integer, not a collection. So it's more a OneToOne relation, isn'it? (If not explain us in comment)

You shouldn't link the primary key (animaux_id) but the entity Animal, because Doctrine does the job for you. It will follow the primary key, will hydrate the Animal object then it will associate it to your SessionChasseurAnimaux entity. In other words, SessionChasseurAnimaux->getAnimaux() will return the hydrated animal object, not an id of the animal. So you should replace :

    #[ORM\OneToOne(mappedBy: 'id', targetEntity: Animaux::class)]
    #[ORM\Column(nullable: true)]
    private ?int $animaux = null;

by

    #[ORM\OneToOne(mappedBy: 'id', targetEntity: Animaux::class)]
    #[ORM\Column(name: "animaux_id", referencedColumnName: "id", nullable: true)]
    private ?int $animaux = null;

Then, don't forget to alter the getter and the setter.

    public function getAnimaux(): ?Animaux
    {
        return $this->animaux;
    }

    public function setAnimaux(?Animaux $animaux_): ChasseurAnimauxSession
    {
        $this->animaux = $animaux;
        return $this;
    }

You should have a look on the symfony/maker-bundle. This bundle will help you to create your entities. It generates all the code! If your entities aren't well described, your forms will be very difficult to build. IMO, this tutorial is very good.

CodePudding user response:

First of all, thank you very much for your answer ! I appreciate

I found a solution and I post you the code that work ( But I don't think it's a good way to do the things )

Controller :

class SaisieFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('animaux_id', EntityType::class,
                ['class' => Animaux::class,
                    'choice_label' => 'espece'])
            ->add('session_chasse_id', EntityType::class,
                ['class' => SessionChasse::class,
                    'choice_label' => 'date'])
            ->add('number_bague', IntegerType::class,
                ['label' => 'Numéro de bague'])
            ->add('sexe', TextType::class,)
            ->add('poids', IntegerType::class,)
            ->add('save', SubmitType::class,
                ['label' => 'Enregistrer']);
    }
}

First Entity ChasseurAniamauxSession :

namespace App\Entity;

use App\Repository\ChasseurAnimauxSessionRepository;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: ChasseurAnimauxSessionRepository::class)]
class ChasseurAnimauxSession
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 10, nullable: true)]
    private ?string $sexe = null;

    #[ORM\Column(nullable: true)]
    private ?int $poids = null;

    #[ORM\OneToMany(mappedBy: 'id', targetEntity: SessionChasse::class)]
    #[ORM\Column(nullable: true)]
    private ?SessionChasse $session_chasse_id = null;

    #[ORM\OneToMany(mappedBy: 'id', targetEntity: Animaux::class)]
    #[ORM\Column(nullable: true)]
    private Animaux|null $animaux_id = null;

    #[ORM\OneToMany(mappedBy: 'id', targetEntity: User::class)]
    #[ORM\Column(nullable: true)]
    private ?int $chasseur_id = null;

    #[ORM\Column(nullable: true)]
    private ?int $number_bague = null;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getSexe(): ?string
    {
        return $this->sexe;
    }

    public function setSexe(?string $sexe): self
    {
        $this->sexe = $sexe;

        return $this;
    }

    public function getPoids(): ?int
    {
        return $this->poids;
    }

    public function setPoids(?int $poids): self
    {
        $this->poids = $poids;

        return $this;
    }

    /**
     * @return SessionChasse|null
     */
    public function getSessionChasseId(): ?SessionChasse
    {
        return $this->session_chasse_id;
    }

    /**
     * @param SessionChasse|null $session_chasse_id
     * @return ChasseurAnimauxSession
     */
    public function setSessionChasseId(?SessionChasse $session_chasse_id): ChasseurAnimauxSession
    {
        $this->session_chasse_id = $session_chasse_id;
        return $this;
    }

    /**
     * @return Animaux|null
     */
    public function getAnimauxId(): ?Animaux
    {
        return $this->animaux_id;
    }

    /**
     * @param Animaux $animaux_id
     * @return ChasseurAnimauxSession
     */
    public function setAnimauxId(Animaux $animaux_id): ChasseurAnimauxSession
    {
        $this->animaux_id = $animaux_id;
        return $this;
    }

    /**
     * @return int|null
     */
    public function getChasseurId(): ?int
    {
        return $this->chasseur_id;
    }

    /**
     * @param int|null $chasseur_id
     * @return ChasseurAnimauxSession
     */
    public function setChasseurId(?int $chasseur_id): ChasseurAnimauxSession
    {
        $this->chasseur_id = $chasseur_id;
        return $this;
    }



    public function getNumberBague(): ?int
    {
        return $this->number_bague;
    }

    public function setNumberBague(?int $number_bague): self
    {
        $this->number_bague = $number_bague;

        return $this;
    }
}

Another Entity Animaux :

namespace App\Entity;

use App\Repository\AnimauxRepository;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: AnimauxRepository::class)]
class Animaux
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 255, nullable: true)]
    private ?string $espece = null;

    public function __toString(): string
    {
        return $this->getId();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getEspece(): ?string
    {
        return $this->espece;
    }

    public function setEspece(?string $espece): self
    {
        $this->espece = $espece;

        return $this;
    }
}

The type :

class SaisieFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('animaux_id', EntityType::class,
                ['class' => Animaux::class,
                    'choice_label' => 'espece'])
            ->add('session_chasse_id', EntityType::class,
                ['class' => SessionChasse::class,
                    'choice_label' => 'date'])
            ->add('number_bague', IntegerType::class,
                ['label' => 'Numéro de bague'])
            ->add('sexe', TextType::class,)
            ->add('poids', IntegerType::class,)
            ->add('save', SubmitType::class,
                ['label' => 'Enregistrer']);
    }
}

I'm going to study the links and the answer that Alexandra gave me, it looks really better than what I've done.

If I do something better, I'll post it here

Alexendre, in effet, we learn the Merise way in course ;)

For finish, a ChasseurAnimauxSession can have a lot of animals. I explain : In this entity, I want to stock for each day of hunt the animals that have been killed by hunters. So I put in this entity the user ( The hunter who killed the animal ), the animal, and the SessionChasse ( Correspond to the day of hunt, a data ) and some informations like the sexe or the weight.

  • Related