CodamAIDocs
Themafertig

Beide Seiten einer Beziehung

CDMS pflegt die Gegenseite einer Beziehung automatisch. Warum der Client die Rückreferenz nicht mitschicken soll.

Ausprägungen
1:11:n von der 1-Seite1:n von der n-Seiten:mRückreferenz mitgeschicktPUT ohne die Liste der Gegenseite

Worum es geht

Eine Beziehung hat in CDMS zwei Enden: company am Mitarbeiter und employees an der Firma. Beide beschreiben dieselbe Verbindung. Das Feld auf der anderen Seite heißt Gegenseite oder Rückreferenz.

flowchart LR
    E["Mitarbeiter Anna"] -->|"company"| C["Firma Codamic"]
    C -->|"employees"| E

CDMS pflegt beide Enden

Sobald CDMS zwei Objekte verbindet, setzt es beide Felder:

Typdu setztCDMS setzt zusätzlich
1:1person.mainPhone = P1P1.person = person
1:ncompany.employees = [Anna]Anna.company = company
n:1anna.company = Cnimmt Anna in C.employees auf
n:mgroup.roles = [R1]nimmt die Gruppe in R1.groups auf

Genauso beim Lösen: Entfernst du Anna aus employees, wird Anna.company leer. Du kannst also jede Beziehung von der Seite aus schreiben, die für deinen Anwendungsfall bequemer ist. Beim Lesen siehst du die Verbindung auf beiden Seiten.

Von welcher Seite schreiben?

Dieselbe Beziehung, zwei Richtungen

Wann: Du schreibst die Firma mit ihrer Liste employees.

  1. 1
    Client→CDMS
    schickt PATCH /company/update/{id} mit "employees": [{ "id": "anna…" }, { "id": "ben…" }]
  2. 2
    CDMS
    setzt bei Anna und Ben company auf diese Firma
  3. 3
    CDMS
    entfernt alle anderen Mitarbeiter aus der Liste, weil die Liste der Zielzustand ist

Ergebnis: Die Firma hat genau Anna und Ben. Siehe Listen als Zielzustand.

Wann: Du schreibst einen Mitarbeiter mit seiner Firma.

  1. 1
    Client→CDMS
    schickt POST /employee/create mit "company": { "id": "c1…" }
  2. 2
    CDMS→Database
    sucht die Firma c1…
  3. 3
    CDMS
    setzt company und nimmt den Mitarbeiter in employees der Firma auf

Ergebnis: Die übrigen Mitarbeiter der Firma bleiben unberührt. Für einzelne Zuordnungen ist das der einfachere Weg.

Wann: Eine Person und ihr Haupttelefon.

Beide Seiten funktionieren gleich: person.mainPhone = { "id": … } oder phone.person = { "id": … }. CDMS setzt jeweils das andere Ende. Zum Ersetzen eines Kindes löst du zuerst das alte (Feld auf null) und setzt dann das neue, am einfachsten in zwei Schritten.

Ergebnis: Genau eine Verbindung zwischen den beiden Objekten.

Wann: Gruppen und Rollen.

Du kannst group.roles schreiben oder role.groups. Beide Wege legen dieselbe Verbindung an, beide sind ein Zielzustand für die Liste, die du schickst. Die Liste der anderen Seite ändert sich nur, soweit sie diese eine Verbindung betrifft.

Ergebnis: Siehe Many-to-Many über eine Verbindungstabelle.

Die Rückreferenz mitschicken?

Beim Zurückschicken gelesener Objekte landet die Rückreferenz leicht im Request, etwa company in jedem Mitarbeiter der Liste employees:

Rückreferenz im Kind
Anfrage
PUT /api/rest/company/update/c1…
{
  "data": {
    "id": "c1…",
    "companyname": "Codamic AG",
    "employees": [
      { "id": "anna…", "firstname": "Anna", "lastname": "Schmidt",
        "company": { "id": "c9…" } }
    ]
  },
  "response": ["+"]
}
Was passiert
Anna gehört danach zu c1…, nicht zu c9….
Die Firma, von der aus geschrieben wird, gewinnt.
Einen Fehler gibt es nicht.
Rückreferenz im Kind
Rückreferenz im Kindzeigt aufErgebnis
fehlt–CDMS setzt sie auf das Elternobjekt
vorhandendas Elternobjektwie oben, doppelt, aber harmlos
vorhandenein anderes Objektwird überschrieben, das Elternobjekt gewinnt
vorhandeneine unbekannte id404, die Anfrage scheitert

Schicke die Rückreferenz deshalb nicht mit. Sie bringt nichts und kann nur schiefgehen.

PUT und die Liste der Gegenseite

PUT beschreibt das ganze Objekt, auch seine Listen. Das gilt für jede Seite einer Beziehung. Schreibst du eine Rolle per PUT und lässt ihre Liste groups weg, löst CDMS alle Verbindungen der Rolle zu Gruppen.

Rolle ändern, ohne die Gruppen zu verlieren
PUT
ganzes Objekt
  • erst die Rolle mit groups lesen
  • groups mit allen ids zurückschicken
  • sonst sind alle Verbindungen weg
PATCH
nur das Geänderte
  • nur die geänderten Felder schicken
  • groups weglassen
  • die Verbindungen bleiben unberührt

Fallen

Wie es weitergeht

Quellen im Code und in der Wissensdatenbank
  • CDMS/cdms-system-layer – AbstractLayer.setReference, removeBackReference, recursiveUpdate (excludeField)
  • hub-backend – ModelDesignService (Spiegelfeld der Gegenseite)
  • CDMS/frontend – server/utils/cdmsInverseCollections.ts
  • CDMS/cdms-integrationtest – AbstractRecursiveTest (createEmployeeWithExistingDepartment_Success), AbstractManyToManyTest, AbstractUpdateTest
Suchen