Worum es geht
Bei einer n:m-Beziehung (Many-to-Many) stehen auf beiden Seiten viele Objekte: Eine Gruppe hat viele Rollen, eine Rolle steckt in vielen Gruppen. Eine relationale Datenbank bildet das mit einer dritten Tabelle ab, der Verbindungstabelle: je Verbindung eine Zeile mit den beiden ids.
In CDMS gibt es dafür zwei Wege:
| MANYTOMANY | Verbindungsmodell | |
|---|---|---|
| modelliert als | ein Feldpaar vom Typ MANYTOMANY | ein eigenes Modell mit zwei MANYTOONE-Feldern |
| Verbindungstabelle | erzeugt der Generator, du siehst sie nicht | ist ein normales Modell mit API und Rollen |
| eigene Felder an der Verbindung | nein | ja, z. B. gültig von/bis |
| im JSON | "roles": [{ "id": … }] | "groups": [{ "group": { "id": … } }] |
| gut für | reine Zuordnung, z. B. Gruppen und Rollen | Zuordnungen mit Eigenschaften, z. B. Mitgliedschaft mit Zeitraum |
Weg 1: MANYTOMANY
erDiagram
ROLE ||--o{ SYSTEM_ROLE_GROUPS : "groups"
GROUP ||--o{ SYSTEM_ROLE_GROUPS : "roles"
ROLE {
uuid id
string name
}
GROUP {
uuid id
string name
}
SYSTEM_ROLE_GROUPS {
uuid role_id
uuid group_id
}
Du legst im Hub an einem der beiden Modelle ein Feld vom Typ MANYTOMANY an, die Gegenseite entsteht mit demselben Typ. Die Verbindungstabelle (hier system-role-groups) erzeugt der Generator. Sie hat nur die beiden Fremdschlüssel.
POST /api/rest/system/group/create
{
"data": {
"name": "Vertrieb",
"roles": [ { "name": "angebot-lesen" }, { "name": "angebot-schreiben" } ]
},
"response": ["id", "name", { "field": "roles", "response": ["id", "name"] }]
}{
"data": {
"id": "g1…",
"name": "Vertrieb",
"roles": [
{ "id": "r1…", "name": "angebot-lesen" },
{ "id": "r2…", "name": "angebot-schreiben" }
]
},
"meta": { "error": false }
}Das geht, weil roles an der Gruppe das Flag CREATE hat. Eine bestehende Rolle verknüpfst du mit ihrer id: "roles": [{ "id": "r1…" }]. Von der anderen Seite geht es genauso: "groups": [{ "id": "g1…" }] an einer Rolle.
Weg 2: ein Verbindungsmodell
erDiagram
USER ||--o{ GROUP2USER : "groups"
GROUP ||--o{ GROUP2USER : "users"
USER {
uuid id
string lastname
}
GROUP2USER {
uuid id
datetime rangeFrom
datetime rangeTo
}
GROUP {
uuid id
string name
}
Hier ist die Verbindung ein eigenes Modell Group2User mit zwei Pflichtfeldern vom Typ MANYTOONE (user, group) und eigenen Feldern (rangeFrom, rangeTo). User.groups und Group.users sind 1:n-Listen auf das Verbindungsmodell, jeweils mit CREATE, UPDATE und DELETE.
- name: "Group2User"
fields:
- name: "user"
relationship: "MANYTOONE"
reference: { id: "m-user", name: "groups" }
rules: { required: true }
- name: "group"
relationship: "MANYTOONE"
reference: { id: "m-group", name: "users" }
rules: { required: true }
- name: "rangeFrom"
"@type": "DateTimeField"
- name: "rangeTo"
"@type": "DateTimeField"
PATCH /api/rest/user/update/u1…
{
"data": {
"id": "u1…",
"groups": [
{ "group": { "id": "e882…" }, "rangeFrom": "2026-10-01 00:00:00" }
]
},
"response": ["+", { "field": "groups", "response": ["+",
{ "field": "group", "response": ["name"] }] }]
}{
"data": {
"id": "u1…",
"lastname": "Müller",
"groups": [
{ "id": "m1…", "rangeFrom": "2026-10-01 00:00:00", "rangeTo": null,
"group": { "id": "e882…", "name": "Vertrieb" } }
]
},
"meta": { "error": false }
}Jeder Eintrag in groups ist eine Verbindungszeile. Ohne id legt CDMS sie an. Das Pflichtfeld user der Zeile schickst du nicht mit, CDMS setzt es selbst, weil die Zeile über den Benutzer angelegt wird. group ist ein reiner Verweis per id.
Verbindung entfernen, ein Ende löschen
Wann: Du lässt eine Rolle aus roles weg, die Beziehung hat kein DELETE-Flag.
-
1CDMS→Databaselöscht die Zeile in der Verbindungstabelle
-
2CDMSdie Rolle selbst bleibt, auch ihre Verbindungen zu anderen Gruppen
Ergebnis: Nur die Verbindung ist weg. Das ist der übliche Fall.
Wann: Du lässt eine Rolle aus roles weg, die Beziehung hat das DELETE-Flag.
-
1CDMS→Databaselöscht die Zeile in der Verbindungstabelle, genau wie ohne Flag
-
2CDMSdie Rolle selbst bleibt, auch ihre Verbindungen zu anderen Gruppen
Ergebnis: An n:m wirkt DELETE nicht: Eine Rolle kann zu weiteren Gruppen gehören, deshalb löst CDMS nur die Verbindung. Auch beim Löschen der Gruppe bleiben ihre Rollen bestehen. Soll eine Rolle wirklich weg, löschst du sie über ihren eigenen Endpunkt.
Wann: Du lässt eine Verbindungszeile aus groups weg, User.groups hat das DELETE-Flag.
-
1CDMS→Databaselöscht die Verbindungszeile
Group2User -
2CDMSdie Gruppe bleibt, weil
Group2User.groupkein DELETE-Flag hat
Ergebnis: Wird der Benutzer gelöscht, löscht CDMS auch seine Verbindungszeilen. Die Gruppen bleiben.
Fallen
Wie es weitergeht
- Beziehungstypen und Flags: Beziehungstypen und Recursive-Flags
- Von welcher Seite schreiben: Beide Seiten einer Beziehung
- Was mit entfernten Mitgliedern passiert: Listen als Zielzustand