Das Projekte-Feature: Von der Datenbank zur Showcase-Seite
Das Projekte-Feature: Von der Datenbank zur Showcase-Seite
19. März 2026 — Seit dem ersten Tag stand ein Projektportfolio auf meiner Roadmap. Heute ist es live — von einer leeren Datenbanktabelle zum vollständig funktionierenden Admin-UI und öffentlichen Portfoliogitter. Hier ist, wie es zusammengekommen ist.
Die Anforderungen
Bevor ich Code schrieb, habe ich kartiert, was ein “Projekt” im Kontext eines professionellen Portfolios braucht:
- Titel und Slug für öffentliche URLs
- Beschreibung (Markdown) und Excerpt für Karten
- Status: active, inactive, completed, archived
- Start-/Enddaten — bei aktiven Projekten ohne Enddatum
- Externe URL — viele Projekte leben auf GitHub oder Firmen-Websites
- Logo/Hero-Bild — aus der Medienbibliothek gewählt
- Tags — freie Labels wie “open-source”, “web”, “data”
- Skills — Many-to-Many mit der globalen Skills-Tabelle
- Berufserfahrungs-Link — optional einem Unternehmen zuordnen
- Bildergalerie — für Screenshots und Visuals
Das Schema-Design
Drei Tabellen wurden benötigt:
projects
Die Haupttabelle mit allem Metadaten — Titel, Slug, Beschreibung, Excerpt, external_url, Status (Ecto Enum), Daten, logo_url, Tags (Postgres-Array), published-Flag und optionalem work_experience_id-Fremdschlüssel.
project_skills
Eine Join-Tabelle für die Many-to-Many-Beziehung mit Skills — zwei Fremdschlüssel und ein Unique-Index.
project_images
Eine Galerie-Tabelle, die sowohl Medienbibliothek-Referenzen (media_id) als auch direkte URLs unterstützt.
Das Ecto-Schema: Assoziationen richtig gemacht
many_to_many :skills, Skill,
join_through: "project_skills",
on_replace: :delete
Das ist der Schlüsseltrick — beim Update eines Projekts verwaltet Ecto automatisch das Einfügen und Löschen von Join-Tabellenzeilen.
Das Admin-UI: Medienbibliothek-Auswahl
Die interessanteste UI-Herausforderung war der Logo-Bildauswähler — ein Vorschau-Thumbnail, ein “Bild auswählen”-Button, der ein Modal mit URL-Eingabe und einem scrollbaren Grid der Medienbibliothek öffnet, plus ein “Entfernen”-Button.
Der Skills-Selektor verwendet Checkbox-Karten in einem responsiven Grid — jeder Skill bekommt eine Checkbox, und ausgewählte Skills werden im @selected_skill_ids-Assign verwaltet.
Die öffentlichen Seiten
Projektübersicht (/projects)
Ein responsives Grid (1→2→3 Spalten) mit Logo, Titel, Datumsbereich, Excerpt, Skill-Pills (lila) und Tag-Pills (türkis).
Projektdetail (/projects/:slug)
Ein einspaltiges, artikel-ähnliches Layout mit Titel, Metadaten, Skills, Tags, Markdown-Beschreibung und Bildergalerie.
Lektionen
-
Many-to-Many in Ecto ist elegant mit
put_assocundon_replace: :delete -
HTML-Formulare senden
""für leere Selects — vor dem Ecto-Cast bereinigen -
URL-Validierung muss lokale
/uploads/-Pfade akzeptieren - Wiederverwendbare Admin-Muster beschleunigen jedes neue Feature
Von leerer Tabelle zur öffentlichen Portfolio-Seite in einer Session — das ist die Phoenix-Entwicklererfahrung.