DiscriminatorMap de Doctrine avec Api-platform

aratinau

Aymeric Ratinaud

Posted on July 5, 2024

DiscriminatorMap de Doctrine avec Api-platform

Le DiscriminatorMap de Doctrine permet une gestion efficace des entités héritées.
Nous allons prendre l'exemple simple d'une classe Vehicle pour créer deux classes qui vont en hériter : Bike et Car
qui ont des attributs différents mais auront les mêmes que Vehicle.
Avec Api-platform, on pourra faire un GET /vehicles pour avoir tous les vehicules
GET bikes pour tous les bikes et GET /cars

<?php

namespace App\Entity;

use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiResource;
use App\Repository\VehicleRepository;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: VehicleRepository::class)]
#[ORM\InheritanceType('JOINED')]
#[ORM\DiscriminatorColumn(name: 'discr', type: 'string')]
#[ORM\DiscriminatorMap([
    'car' => Car::class,
    'bike' => Bike::class
])]
#[ApiResource]
#[ApiFilter(OrderFilter::class)]
class Vehicle
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 255)]
    #[ApiFilter(SearchFilter::class, strategy: 'partial')]
    private ?string $brand = null;

    #[ORM\Column]
    private ?\DateTimeImmutable $createdAt = null;

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

    public function getBrand(): ?string
    {
        return $this->brand;
    }

    public function setBrand(string $brand): static
    {
        $this->brand = $brand;

        return $this;
    }

    public function getCreatedAt(): ?\DateTimeImmutable
    {
        return $this->createdAt;
    }

    public function setCreatedAt(\DateTimeImmutable $createdAt): static
    {
        $this->createdAt = $createdAt;

        return $this;
    }
}
Enter fullscreen mode Exit fullscreen mode
<?php

namespace App\Entity;

use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiResource;
use App\Repository\BikeRepository;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: BikeRepository::class)]
#[ApiResource]
#[ApiFilter(OrderFilter::class)]
class Bike extends Vehicle
{
    #[ORM\Column]
    private ?bool $hasCarrier = null;

    public function hasCarrier(): ?bool
    {
        return $this->hasCarrier;
    }

    public function setHasCarrier(bool $hasCarrier): static
    {
        $this->hasCarrier = $hasCarrier;

        return $this;
    }
}
Enter fullscreen mode Exit fullscreen mode
<?php

namespace App\Entity;

use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\ApiResource;
use App\Repository\CarRepository;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: CarRepository::class)]
#[ApiResource]
#[ApiFilter(OrderFilter::class)]
class Car extends Vehicle
{
    #[ORM\Column]
    private ?int $numberOfDoors = null;

    public function getNumberOfDoors(): ?int
    {
        return $this->numberOfDoors;
    }

    public function setNumberOfDoors(int $numberOfDoors): static
    {
        $this->numberOfDoors = $numberOfDoors;

        return $this;
    }
}
Enter fullscreen mode Exit fullscreen mode

Tout ce fait avec

#[ORM\InheritanceType('JOINED')]
#[ORM\DiscriminatorColumn(name: 'discr', type: 'string')]
#[ORM\DiscriminatorMap([
    'car' => Car::class,
    'bike' => Bike::class
])]
Enter fullscreen mode Exit fullscreen mode

InheritanceType peut également être SINGLE_TABLE ce qui signifie que vous n'aurez qu'une seule table pour toutes vos entités

N'oubliez pas également sur les autres classes de rajouter extends Vehicle

Fusée 🚀

💖 💪 🙅 🚩
aratinau
Aymeric Ratinaud

Posted on July 5, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related