CodamAIDocs
Themafertig

Löschen durch Ändern

Ein PUT oder PATCH, das ein abhängiges Kind aus einer Liste oder einer Referenz entfernt, löscht es. Hier steht, wann das passiert.

Ausprägungen
PUT: Liste fehlt → alle abhängigen Kinder gelöschtPUT/PATCH: Kind fehlt in der Liste → gelöschtPATCH: Liste fehlt → unverändertEinzelreferenz null → gelöschtohne DELETE-Flag → nur abgekoppeltRollen und Hooks

Worum es geht

Nicht nur DELETE löscht. Auch ein PUT oder PATCH am Elternobjekt kann Kinder löschen, nämlich dann, wenn ein abhängiges Kind (Beziehung mit DELETE-Flag) danach nicht mehr dazugehört. Das passiert, wenn

  • eine Liste ohne das Kind geschickt wird,
  • eine Liste als leer gilt,
  • eine Einzelreferenz geleert wird.

Das ist gewollt: Eine Rechnungsposition, die aus der Rechnung fällt, hat ohne Rechnung keinen Sinn. Es ist aber auch die häufigste Art, versehentlich Daten zu löschen.

Vorher und nachher

Ein Kontakt mit einem Haupttelefon mainPhone und weiteren Telefonen phones. Beide Beziehungen haben das DELETE-Flag.

FeldvorherAnfragenachher
phonesP2, P3"phones": [{ "id": "P2…" }]P2; P3 gelöscht
phonesP2, P3"phones": []leer; P2 und P3 gelöscht
mainPhoneP1"mainPhone": nullleer; P1 gelöscht
phonesP2, P3PUT ohne phonesleer; P2 und P3 gelöscht
phonesP2, P3PATCH ohne phonesP2, P3, unverändert

Die letzten beiden Zeilen sind der Unterschied zwischen PUT und PATCH: Bei PUT heißt „fehlt“ dasselbe wie „leer“, bei PATCH heißt „fehlt“ „nicht anfassen“.

PATCH, das P3 löscht
Anfrage
PATCH /api/rest/crm/contact/update/c052…
{
  "data": {
    "id": "c052…",
    "phones": [ { "id": "P2…" } ]
  },
  "response": ["id", { "field": "phones", "response": ["id", "number"] }]
}
Antwort
{ "data": { "id": "c052…",
            "phones": [ { "id": "P2…", "number": "0611-17277000" } ] },
  "meta": { "error": false } }

P3 ist danach nicht nur aus der Liste verschwunden, sondern gelöscht. /phone/read/P3… liefert 404.

Wann gelöscht wird

Ein bestehendes Kind nach PUT oder PATCH
VerbFeld in der AnfrageKind darin enthaltenFlag DELETEErgebnis für das Kind
–Liste oder Referenzja–bleibt verbunden
–Liste ohne das Kind, [] oder nullneinjagelöscht
–Liste ohne das Kind, [] oder nullneinneinabgekoppelt, bleibt bestehen
PUTfehlt–jagelöscht (fehlt = leer)
PUTfehlt–neinabgekoppelt (fehlt = leer)
PATCHfehlt––unverändert
–Einzelreferenz null–jagelöscht

„Enthalten“ heißt: Das Kind steht mit seiner id in der Liste bzw. der Referenz. Welche Felder du sonst mitschickst, spielt dafür keine Rolle. Siehe Listen als Zielzustand.

Was dabei passiert

  1. 1
    Client→CDMS
    schickt PATCH /contact/update/c052… mit phones: [P2]
  2. 2
    CDMS
    prüft Sichtbarkeit und Änderungsrolle des Kontakts
  3. 3
    CDMS
    vergleicht die Liste mit dem gespeicherten Stand: P3 fehlt
  4. 4
    CDMS
    phones hat DELETE → P3 wird gelöscht
    Ohne DELETE-Flag würde P3 nur abgekoppelt: Sein Verweis auf den Kontakt wird leer, P3 bleibt.
  5. 5
    CDMS
    prüft die Löschrolle des Telefon-Modells (oder eine Feldrolle an phones)
  6. 6
    CDMS→Client
    Rolle fehlt → 403, nichts wird gespeichert, auch die übrigen Änderungen nicht
  7. 7
    Hook
    DELETE-Hooks von P3 laufen, zusammen mit den UPDATE- bzw. PATCH-Hooks des Kontakts
  8. 8
    CDMS→Database
    löscht P3 samt seinen eigenen abhängigen Kindern und Dateien, speichert den Kontakt, liest zurück

Für das gelöschte Kind gilt alles aus Abhängige Objekte (Kaskaden): Es braucht die Löschrolle seines Modells, seine eigenen abhängigen Kinder gehen mit, seine übrigen Beziehungen werden gelöst.

Fallen

Wie es weitergeht

Quellen im Code und in der Wissensdatenbank
  • CDMS/cdms-system-layer – AbstractLayer.recursiveUpdate, recursivePatch, reduceToTargetState, detachOrDeleteModel, detachOrDeleteMember, recursiveDelete
  • CDMS/cdms-integrationtest – AbstractUpdateTest (updateOneToManyListRecursiveDeleteReallyDeletes), AbstractRecursiveUpdate, AbstractRecursivePatch
  • documentation/20-api/04-schreibsemantik.md
Suchen