CodamAIDocs
Topicdone

Dependent objects (cascades)

When children are deleted along with the parent and when they are only unlinked, that every child needs its own delete role, and that a missing role rolls back everything.

Variants
with DELETE flag → deleted alongwithout DELETE flag → unlinkedper relation type: 1:1, 1:n, n:1, n:m, join modelacross several levelsrole missing anywhere → everything rolled backfield role instead of class role

What this is about

An object rarely stands alone. A company has employees, an invoice has items, an employee belongs to a department. When you delete an object, CDMS walks through each of its relations and decides for every connected object:

  • delete along if the relation has the flag DELETE. The connected object is then a dependent child: it only lives together with its parent.
  • unlink if the relation has no DELETE. The connected object stays, only the reference to the deleted object disappears.

A child that is deleted along is treated exactly like the object itself: its relations are walked through as well. This way a delete can reach across many levels. This chain reaction is called a cascade.

An example as a tree

A company modeled like this:

FieldTypeFlag DELETE
Company.employees1:n to employeeyes
Employee.phones1:n to phone numberyes
Company.logo1:1 to a file modelyes
Company.mainAddress1:1 to addressno
Employee.departmentn:1 to departmentno

DELETE /company/delete/c4… works like this:

flowchart TB
    C["Company CodamIC"]:::weg --> E1["Employee Anna"]:::weg
    C --> E2["Employee Ben"]:::weg
    C --> L["Logo (file)"]:::weg
    C -.-> A["Address Wiesbaden"]:::bleibt
    E1 --> P1["Phone 0611-1"]:::weg
    E2 --> P2["Phone 0611-2"]:::weg
    E2 --> P3["Phone 0170-3"]:::weg
    E1 -.-> D["Department IT"]:::bleibt
    E2 -.-> D
    classDef weg fill:#fdecea,stroke:#c62828,color:#8e0000
    classDef bleibt fill:#e8f5e9,stroke:#2e7d32,color:#1b5e20

Red is deleted, green stays. Solid lines are relations with the DELETE flag, dashed lines are relations without it.

  • Anna, Ben and their phone numbers are deleted, across two levels.
  • The logo is deleted, including the file content in storage. See Deleting file models.
  • The address stays. It only loses its reference to the company.
  • The IT department stays. Anna and Ben disappear from its list employees.
What happens to the connected object when X is deleted
Relation on XFlag DELETEResult
1:1yesthe child is deleted
1:1nothe child stays, its reference to X is cleared
1:n (list)yesall children in the list are deleted
1:n (list)noall children stay, their reference to X is cleared
n:1 (X points to a parent)nothe parent stays, X disappears from its list
n:1 (X points to a parent)yesthe parent is deleted
n:mnothe connections disappear, the partners stay
n:myesas without the flag: the connections disappear, the partners stay

With a join model (n:m with its own fields, such as Group2User) there are two 1:n relations. If User.groups has the DELETE flag, CDMS deletes the user’s join rows along with the user. The groups stay, because Group2User.group has no DELETE flag. See Many-to-many through a join table.

Unlinking in detail

Unlinking means: on the connected object, CDMS clears the reference back to the deleted object and saves it. The connected object itself stays, with all its other fields.

The two paths
Delete along
relation with DELETE
  • the child disappears together with its own dependent children
  • needs the delete role of the child model
  • DELETE hooks of the child run
  • file content of the child is removed
Unlink
relation without DELETE
  • the object stays, only the reference becomes empty
  • no role of the connected model needed
  • no DELETE hooks
  • files stay untouched

Because unlinking is not a delete, you need no role on the connected model for it. You may delete an employee with employee-delete, even without any role on the department. The department stays and no longer has the employee in employees.

Roles in the cascade

CDMS checks the delete role for every row that disappears, against the model of that row. To delete a company together with its employees, you need company-delete and employee-delete.

The role check in a cascade

When: company-delete and employee-delete

  1. 1
    CDMS
    company: company-delete present
  2. 2
    CDMS
    every employee: employee-delete present
  3. 3
    CDMS→Database
    deletes company and employees

Result: 200

When: only company-delete, the company has one employee

  1. 1
    CDMS
    company: company-delete present
  2. 2
    CDMS
    employee: employee-delete missing
  3. 3
    CDMS→Client
    403 missing-permission|employee-delete, the transaction is rolled back

Result: Company and employee are still there, unchanged. There is no "half deleted".

When: The relation Vault.notes has its own delete role vault-notes-delete

  1. 1
    CDMS
    vault: vault-delete present
  2. 2
    CDMS
    every note: vault-notes-delete or note-delete present?
  3. 3
    CDMS→Database
    deletes vault and notes

Result: The field role allows deleting the notes only along this path. Deleting a note directly through /note/delete/{id} still requires note-delete. If both are missing, the error names the field role: 403 missing-permission|vault-notes-delete.

A field role applies to one level only. If a note has dependent children of its own, each of them again needs the role of its model or a field role on the note’s relation. See Permissions on relations (field roles).

Pitfalls

What comes next

Sources in the code and the knowledge base
  • CDMS/cdms-system-layer – AbstractLayer.recursiveDelete, removeBackReference, enterField, grantedByField
  • CDMS/cdms-authorization – AbstractAuthorizationLayer.deleteAccessAllowedByClass, accessGrantedByField
  • CDMS/cdms-integrationtest – AbstractRecursiveTest, AbstractRecursiveDelete, AbstractRoleDenialTest (cascadedDeleteNeedsTheDeleteRoleOfTheChild, deleting an employee without a department role), AbstractFieldRoleTest (cascadedDeleteThroughTheFieldRole, cascadedDeleteWithoutTheFieldRoleIsRefused), AbstractRecursiveFileDeleteTest
  • documentation/20-api/04-schreibsemantik.md, 30-daten-und-persistenz/03-beziehungen.md
Search