Bonjour à toutes et à tous,

Je viens soliciter votre aide concernant le développement de mon code.
Je m'explique, je développe une agence de location, j'ai donc comme entité :
Voiture
Location

Une location peut contenir plusieurs voitures, à l'inverse une voiture peut-être dans plusieurs locations (une voiture peut être louée plusieurs fois dans le même mois).

J'ai donc une relation many-to-many, j'ai bien Doctrine qui m'a généré ma table. Cependant, je voudrais pouvoir ajouter une quantité par voiture. Une même location peut avoir :
Une Opel (avec la quantité de 3, le client souhaite 3 Opel)
Une Mercedes (avec la quantité de 2, le client souhaite 2 Mercedes)
...

Je ne vais pas ajouter cet attribut "quantitée" à mon entité "voiture" ni à l'entité "location".
Se sera bien un attibut de la table intermédiaire. Mais quelle logique dois-je suivre pour réaliser ceci.

J'ai bien un form concernant l'entité location avec l'entité voiture qui est en select multiple. Tout s'enregistre bien, j'ai bien l'id de ma location ainsi que l'id des différentes voitures mais j'aimerai ajouter la quantité également.

Si vous pouvez me guider :)

Bonne journée.

5 réponses


Salut,

Tu vas être obligé de créer une entité dédiée pour cela.
Tu auras une entité Voiture avec une relation OneToMany vers la nouvelle entité VoitureLocation, une entité Location qui aura une relation OneToMany vers VoitureLocation, et la nouvelle entité VoitureLocation qui aura 2 relations ManyToOne vers Location et Voiture, ainsi qu'un attribut quantité....

class Voiture {
...
/**
* @ORM\OneToMany(targetEntity="App\Entity\VoitureLocation", mappedBy="voiture", cascade={"persist"})
*/
private $voitureLocation

class Location {
...
/**
* @ORM\OneToMany(targetEntity="App\Entity\VoitureLocation", mappedBy="location", cascade={"persist"})
*/
private $voitureLocation

class VoitureLocation {
/**
 * @ORM\ManyToOne(targetEntity="App\Entity\Voiture", inversedBy="voitureLocation")
 */
private $voiture;

/**
 * @ORM\ManyToOne(targetEntity="App\Entity\Location", inversedBy="voitureLocation")
 */
private $location;

/**
 * @ORM\Column(name="quantite", type="integer")
 */
private $quantite;
Yser
Auteur

Bonsoir Digivia,
Un grand merci pour ta réponse, effectivement j'ai réalisé pas mal de recherches et c'est la solution adéquate. Cependant, c'est surtout savoir comment la quantité va se rapporter à la voiture en question, est-ce que dans twig je dois ajouter un champ supplémentaire à côté de chaque voiture ?

Pour le moment j'ai une relation many-to-one (voiture vers location). Pour remplire ce formulaire, l'utilisateur sélectionne les dates de location, ensuite il choisit les voitures (dans une liste déroulante avec un select multiple). Lors de la soumission, j'ai bien l'entité location avec l'id de l'utilisateur et j'ai bien l'entité intermédiaire qui reprend les différentes voitures et l'id de la location.

Si je travaille avec cette nouvelle entité intermédiaire avec l'attribut quantité, la soumission se fera au niveau de cette entité. Mais pour qu'elle se fasse, il faut que l'entité location soit déjà ajoutée. Hors dans mon cas il faudrait qu'il crée la location pour ensuite pouvoir alimenter l'entitée intermédiaire. C'est la que je bloque, comment réaliser cette quantité par voiture... Je sais pas si je suis assez claire, je cache pas que je m'enbrouille tout seul donc si vous comprenez pas tout c'est assez normal. Si vous souhaitez voir des morceaux de codes ou que je sois plus claire, n'hésitez pas à m'en faire par.

Bonne soirée.

Au fait je me prend vraiment la tête, du coups à l'aide de cette nouvelle entitée intermédiaire, le formulaire se fera sur cette entitée ?
Et c'est dans ce formulaire que j'y ajouterai "EntityType::class" pour alimenter mon entité location ?

Par contre j'abandonne l'idée du sélect multiple, je m'oriente vers un tableau reprenant chaque voiture et la possibilitée d'y ajouter une quantitée ? Qu'en pensez vous ?

Perso je ferais un second formType "VoitureLocation", avec à l'intérieur un champ EntityType pour sélectionner le véhicule et un autre IntegerType pour la quantité, et j'ajouterais ce FormType dans mon form principal.
J'avoue que je n'ai jamais eu ce cas à traiter, alors à tester...

Yser
Auteur

Ok ok Digivia, je teste ceci et je te tiens informé, merci pour ton aide.

Yser
Auteur

Alors voilà où j'en suis actuellement, j'ai mes 3 entités, j'ai également 2 form. Je me suis inspiré d'une question similaire. Cependant, je suis perdu au niveau des controlleurs, qui je dois appeler en premier, que dois-je renvoyer, comment afficher chaque borne et cet attribut quantité (j'ai commencé en parlant de location de voiture pour que ce soit plus claire mais il s'agit de location de borne d'arcades. Voici mes entités ainsi que mes formTypes :

Entité arcade :

    /**
     * @ORM\OneToMany(targetEntity="LeasingArcade", mappedBy="arcade", cascade={"persist"})
     */
    private $leasingArcades;

    public function __construct()
    {
        $this->leasingArcades = new ArrayCollection();
    }

    /**
     * Add leasingArcade
     * @param \AppBundle\Entity\LeasingArcade $leasingArcade
     * @return Arcade
     */
    public function addLeasingArcade(\AppBundle\Entity\LeasingArcade $leasingArcade)
    {
        $this->leasingArcades[] = $leasingArcade;
        if ($leasingArcade->getArcade() !== $this) {
            $leasingArcade->setArcade($this);
        }
        return $this;
    }

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

Entité leasing :

    /**
     * @ORM\OneToMany(targetEntity="LeasingArcade", mappedBy="leasing", cascade={"persist"})
     */
    private $leasingArcades; 

    public function __construct()
    {
        $this->leasingArcades = new ArrayCollection();
    }

    /**
     * Add leasingArcade
     * @param \AppBundle\Entity\LeasingArcade $leasingArcade
     * @return Leasing
     */
    public function addLeasingArcade(\AppBundle\Entity\LeasingArcade $leasingArcade)
    {
        $this->leasingArcades[] = $leasingArcade;
        if ($leasingArcade->getLeasing() !== $this) {
            $leasingArcade->setLeasing($this);
        }
        return $this;
    }

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

Entité LeasingArcade :

    /**
     * @ORM\ManyToOne(targetEntity="Leasing", inversedBy="leasingArcades")
     * @ORM\JoinColumn(name="leasing_id", referencedColumnName="id", nullable = false)
     */
    private $leasing;

    /**
     * @ORM\ManyToOne(targetEntity="Arcade", inversedBy="leasingArcades")
     * @ORM\JoinColumn(name="arcade_id", referencedColumnName="id", nullable = false)
     */
    private $arcade;

    /**
     * @var int
     *
     * @ORM\Column(name="quantity", type="smallint")
     */
    private $quantity;

    /**
     * Set quantity
     * @param integer $quantity
     * @return LeasingArcade
     */
    public function setQuantity($quantity)
    {
        $this->quantity = $quantity;
        return $this;
    }

    /**
     * Get quantity
     * @return int
     */
    public function getQuantity()
    {
        return $this->quantity;
    }

     /**
     * Set leasing
     * @param \AppBundle\Entity\Leasing $leasing
     * @return LeasingArcade
     */
    public function setLeasing(\AppBundle\Entity\Leasing $leasing)
    {
        $this->leasing = $leasing;
        if ($leasing->getLeasingArcades() !== $this) {
            $leasing->addLeasingArcade($this);
        }
        return $this;
    }

    /**
     * Get leasing
     * @return \AppBundle\Entity\Leasing
     */
    public function getLeasing()
    {
        return $this->leasing;
    }

    /**
     * Set arcade
     * @param \AppBundle\Entity\Arcade $arcade
     * @return LeasingArcade
     */
    public function setArcade(\AppBundle\Entity\Arcade $arcade)
    {
        $this->arcade = $arcade;
        if ($arcade->getLeasingArcades() !== $this) {
            $arcade->addLeasingArcade($this);
        }
        return $this;
    }

    /**
     * Get arcade
     * @return \AppBundle\Entity\Arcade
     */
    public function getArcade()
    {
        return $this->arcade;
    }

Mon form concernant "Leasing" :

class LeasingType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
        ->add('nameEvent')
        ->add('typeEvent')
        ->add('dateStart', DateType::class, ['widget' => 'single_text', 'html5' => false, 'format' => 'dd / MM / yyyy'])
        ->add('dateEnd', DateType::class, ['widget' => 'single_text', 'html5' => false, 'format' => 'dd / MM / yyyy'])
        ->add('locality')
        ->add('leasingArcades', CollectionType::class, [
            'entry_type' => LeasingArcadeType::class,
            'allow_add' => false,
        ]);
    }

Mon form concernant "LeasingArcade" :

class LeasingArcadeType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('quantity');
    }
 }

Si il faut des informations supplémentaires ou autres, faites le moi savoir :)