DiscriminatorMap de Doctrine avec Api-platform



This content originally appeared on DEV Community and was authored by Aymeric Ratinaud

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;
    }
}
<?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;
    }
}
<?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;
    }
}

Tout ce fait avec

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

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 🚀


This content originally appeared on DEV Community and was authored by Aymeric Ratinaud