Worum es geht
Ein Objekt steht selten allein. Eine Firma hat Mitarbeiter, eine Rechnung hat Positionen, ein Mitarbeiter gehört zu einer Abteilung. Löschst du ein Objekt, geht CDMS jede seiner Beziehungen durch und entscheidet für jedes verbundene Objekt:
- mitlöschen, wenn die Beziehung das Flag
DELETEhat. Das verbundene Objekt ist dann ein abhängiges Kind: Es lebt nur mit seinem Elternobjekt. - abkoppeln, wenn die Beziehung kein
DELETEhat. Das verbundene Objekt bleibt bestehen, nur der Verweis auf das gelöschte Objekt verschwindet.
Ein mitgelöschtes Kind wird genauso behandelt wie das Objekt selbst: Auch seine Beziehungen werden durchgegangen. So kann eine Löschung über viele Stufen reichen. Diese Kettenreaktion heißt Kaskade.
Ein Beispiel als Baum
Eine Firma mit dieser Modellierung:
| Feld | Typ | Flag DELETE |
|---|---|---|
Company.employees | 1:n auf Mitarbeiter | ja |
Employee.phones | 1:n auf Telefonnummer | ja |
Company.logo | 1:1 auf ein Datei-Modell | ja |
Company.mainAddress | 1:1 auf Adresse | nein |
Employee.department | n:1 auf Abteilung | nein |
DELETE /company/delete/c4… wirkt so:
flowchart TB
C["Firma CodamIC"]:::weg --> E1["Mitarbeiter Anna"]:::weg
C --> E2["Mitarbeiter Ben"]:::weg
C --> L["Logo (Datei)"]:::weg
C -.-> A["Adresse Wiesbaden"]:::bleibt
E1 --> P1["Telefon 0611-1"]:::weg
E2 --> P2["Telefon 0611-2"]:::weg
E2 --> P3["Telefon 0170-3"]:::weg
E1 -.-> D["Abteilung IT"]:::bleibt
E2 -.-> D
classDef weg fill:#fdecea,stroke:#c62828,color:#8e0000
classDef bleibt fill:#e8f5e9,stroke:#2e7d32,color:#1b5e20
Rot wird gelöscht, grün bleibt. Durchgezogene Linien sind Beziehungen mit DELETE-Flag, gestrichelte ohne.
- Anna, Ben und ihre Telefonnummern werden gelöscht, über zwei Stufen.
- Das Logo wird gelöscht, samt Dateiinhalt im Speicher. Siehe Datei-Modelle löschen.
- Die Adresse bleibt. Sie verliert nur ihren Verweis auf die Firma.
- Die Abteilung IT bleibt. Anna und Ben verschwinden aus ihrer Liste
employees.
Abkoppeln oder mitlöschen, je Beziehungstyp
| Beziehung an X | Flag DELETE | Ergebnis |
|---|---|---|
| 1:1 | ja | das Kind wird gelöscht |
| 1:1 | nein | das Kind bleibt, sein Verweis auf X wird geleert |
| 1:n (Liste) | ja | alle Kinder in der Liste werden gelöscht |
| 1:n (Liste) | nein | alle Kinder bleiben, ihr Verweis auf X wird geleert |
| n:1 (X zeigt auf ein Elternobjekt) | nein | das Elternobjekt bleibt, X verschwindet aus seiner Liste |
| n:1 (X zeigt auf ein Elternobjekt) | ja | das Elternobjekt wird gelöscht |
| n:m | nein | die Verbindungen verschwinden, die Partner bleiben |
| n:m | ja | wie ohne Flag: die Verbindungen verschwinden, die Partner bleiben |
Bei einem Verbindungsmodell (n:m mit eigenen Feldern, etwa Group2User) sind es zwei 1:n-Beziehungen. Hat User.groups das DELETE-Flag, löscht CDMS mit dem Benutzer seine Verbindungszeilen. Die Gruppen bleiben, weil Group2User.group kein DELETE-Flag hat. Siehe Many-to-Many über eine Verbindungstabelle.
Abkoppeln im Einzelnen
Abkoppeln heißt: CDMS leert beim verbundenen Objekt den Verweis zurück auf das gelöschte Objekt und speichert es. Das verbundene Objekt selbst bleibt, mit allen anderen Feldern.
- das Kind verschwindet mit seinen eigenen abhängigen Kindern
- braucht die Löschrolle des Kindmodells
- DELETE-Hooks des Kindes laufen
- Dateiinhalt des Kindes wird entfernt
- das Objekt bleibt, nur der Verweis wird leer
- keine Rolle des verbundenen Modells nötig
- keine DELETE-Hooks
- Dateien bleiben unberührt
Weil Abkoppeln kein Löschen ist, brauchst du dafür keine Rolle am verbundenen Modell. Einen Mitarbeiter darfst du mit employee-delete löschen, auch ohne jede Rolle an der Abteilung. Die Abteilung bleibt und hat ihn danach nicht mehr in employees.
Rollen in der Kaskade
CDMS prüft die Löschrolle für jede Zeile, die verschwindet, und zwar gegen das Modell dieser Zeile. Wer eine Firma samt Mitarbeitern löschen will, braucht company-delete und employee-delete.
Wann: company-delete und employee-delete
-
1CDMSFirma:
company-deletevorhanden -
2CDMSjeder Mitarbeiter:
employee-deletevorhanden -
3CDMS→Databaselöscht Firma und Mitarbeiter
Ergebnis: 200
Wann: nur company-delete, die Firma hat einen Mitarbeiter
-
1CDMSFirma:
company-deletevorhanden -
2CDMSMitarbeiter:
employee-deletefehlt -
3CDMS→Client403
missing-permission|employee-delete, die Transaktion wird zurückgerollt
Ergebnis: Firma und Mitarbeiter sind danach unverändert da. Es gibt kein „halb gelöscht“.
Wann: Die Beziehung Vault.notes hat eine eigene Löschrolle vault-notes-delete
-
1CDMSTresor:
vault-deletevorhanden -
2CDMSjede Notiz:
vault-notes-deleteodernote-deletevorhanden? -
3CDMS→Databaselöscht Tresor und Notizen
Ergebnis: Die Feldrolle erlaubt das Löschen der Notizen nur über diesen Weg. Eine Notiz direkt über /note/delete/{id} zu löschen, verlangt weiter note-delete. Fehlt beides, nennt der Fehler die Feldrolle: 403 missing-permission|vault-notes-delete.
Eine Feldrolle gilt nur für eine Stufe. Hat eine Notiz selbst abhängige Kinder, braucht jedes davon wieder die Rolle seines Modells oder eine Feldrolle an der Beziehung der Notiz. Siehe Rechte auf Beziehungen (Feldrollen).
Fallen
Wie es weitergeht
- Die Schritte eines DELETE: Der Ablauf eines DELETE
- Kinder, die durch PUT oder PATCH aus einer Liste fallen: Löschen durch Ändern
- Die Flags selbst: Beziehungstypen und Recursive-Flags