Ein Tagging-Konzept für Symfony

Für ein aktuelles Projekt sollen alle Informationen für den Nutzer schnell erreichbar, filterbar und markierbar gemacht werden. Diese Voraussetzungen lassen sich am besten mit Tags bereitstellen.

Ein Tag ist dabei nicht mehr, als ein einfacher Name, der einem Objekt zugeordnet wird. Nach einem solchen Namen kann dann gesucht werden, sodass die Website nur zutreffende Objekte herausfiltert und diese möglichst übersichtlich dem Nutzer verfügbar macht.

In dem Projekt gibt es nun einige unterschiedliche Objekte: Benutzer, Gruppen, Dashboards, Widgets, Tabellen, usw. Jeder Entity in der Datenbank eine neue Spalte hinzuzufügen, um darin die Zuordnung für einen Tag zu speichern, ist definitiv nicht die Lösung, die wir suchen. Wie denn dann?

Eine Superklasse für Entities

Um dem oberen Ansatz aus dem Wege zu gehen, braucht man neben der Entity für die Tags noch eine Tabelle, die einem Objekt einen Tag zuordnet. In diesem Fall eine Many-to-Many Beziehung. Das Objekt könnte nun aber alles Mögliche sein, weshalb man eine Form braucht, die für ein wenig Gleichheit sorgt.

Man erstellt eine Superklasse, von der jede „tagbare“ Entity erben kann:

Gleichzeitig ersetzt diese Super-Entity das ID-Attribut in allen anderen Entities. Der Grund dafür ist die Einheitlich Zählung: Ab hier wird nicht mehr jede einzelne Tabelle mit einer ID geführt, sondern es existiert eine globale ID über alle „tagbaren“ Tabellen, die in der neuen taggable-Tabelle geführt wird.

Hinzu kommt, dass Doctrine alle dazugehörigen Klassen für uns speichert. Die Annotation DiscriminatorColumn speichert zudem in der Spalte child_class_type die dazugehörige Klasse als String. Somit kann das Objekt im nachhinein wieder automatisch hergestellt werden!

Aufbau der „tagbaren“ Entities

Da keine individuelle ID mehr existiert, verschwinden die Variable und der Getter für ID aus allen „tagbaren“ Entities:

Die übergeordnete ID ist protected und damit weiterhin ganz normal verwendbar. Theoretisch kann man auch die Getter stehen lassen, da sieh einfach überschrieben würden. Auch die Benutzer-Entity, welche AdvancedUserInterface implementiert, kann ge-taggt werden.

Die Tag-Entity

… könnte z.B. so aussehen:

Zu beachten ist, dass für $entities eine Referenz für die TaggableEntity und für eine Speudotabelle (hier @JoinTable) angegeben ist. Den Rest erledigt Doctrine!

Und das war es auch schon! Jetzt können nach Belieben Tags erstellt und den anderen „tagbaren“ Entities zugeordnet werden. 🙂

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.