ManyToMany zwischen Task und Tag
ManyToMany zwischen Task und Tag
~15 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
EINE Task kann MEHRERE Tags haben, EIN Tag kann auf MEHREREN Tasks liegen – die KLASSISCHE Viele-zu-viele-Beziehung, GENAU wie in der Symfony-Schulung (Kapitel 32).
Die tags-Property auf Task
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
// ... innerhalb der Klasse:
#[ORM\ManyToMany(targetEntity: Tag::class, inversedBy: 'tasks')]
#[Groups(['task:read', 'task:write'])]
private Collection $tags;
public function __construct()
{
$this->tags = new ArrayCollection();
}
public function getTags(): Collection
{
return $this->tags;
}
public function addTag(Tag $tag): static
{
if (!$this->tags->contains($tag)) {
$this->tags->add($tag);
}
return $this;
}
public function removeTag(Tag $tag): static
{
$this->tags->removeElement($tag);
return $this;
}Achtung: KEIN set-Setter für tags, sondern add/remove – der Symfony Serializer erkennt dieses Muster AUTOMATISCH und ruft BEIM Deserialisieren einer Collection die passenden add-/remove-Methoden auf, GENAU wie bei einer normalen Symfony-Form.
Die inverse Seite auf Tag
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
// ... innerhalb der Klasse:
#[ORM\ManyToMany(targetEntity: Task::class, mappedBy: 'tags')]
private Collection $tasks;
public function __construct()
{
$this->tasks = new ArrayCollection();
}BEWUSST OHNE #[Groups] auf tasks – Tag ist seit Kapitel 12 schreibgeschützt und muss die zugehörigen Tasks NICHT in der API-Antwort zeigen, um die Beziehung NUTZBAR zu machen.
Migration erstellen
docker compose exec php bin/console make:migration
docker compose exec php bin/console doctrine:migrations:migrate --no-interactionERZEUGT eine ZUSÄTZLICHE Join-Tabelle (task_tag) – GENAU das ÜBLICHE Datenbankmuster für Viele-zu-viele-Beziehungen, VOLLSTÄNDIG von Doctrine verwaltet.
Eine Task mit Tags erstellen
curl -k -X POST https://localhost/api/tasks \
-H 'Content-Type: application/json' \
-d '{"title": "Deployment vorbereiten", "project": "/api/projects/1", "tags": ["/api/tags/1", "/api/tags/2"]}'tags als ARRAY von IRIs – GENAU dasselbe Prinzip wie das EINZELNE project-Feld, nur PLURAL für eine Viele-zu-viele-Beziehung.
Tipp: #[Assert\Count(min: 1)] aus Kapitel 21 ließe sich HIER einsetzen, um MINDESTENS einen Tag pro Task zu erzwingen – für UNSER Projekt bleiben Tags OPTIONAL.