Skip to content

Commit ca65f67

Browse files
author
Pavlo Kulyk
committed
feat: implement cascading deletion for related records in delete endpoint
1 parent ab16fde commit ca65f67

File tree

1 file changed

+26
-15
lines changed

1 file changed

+26
-15
lines changed

adminforth/modules/restApi.ts

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,6 +1452,30 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
14521452
}
14531453
}
14541454
});
1455+
async function handleCascadeOnDelete(parentResource: AdminForthResource, parentId: any) {
1456+
const adminforth = this.adminforth;
1457+
for (const resource of adminforth.config.resources) {
1458+
if (resource.resourceId === parentResource.resourceId) continue;
1459+
const foreignKeyColumn = resource.columns.find(c => c.foreignResource?.resourceId === parentResource.resourceId
1460+
);
1461+
if (!foreignKeyColumn) continue;
1462+
const deleteStrategy = foreignKeyColumn.foreignResource?.onDelete ?? 'null';
1463+
const primaryKeyColumn = resource.columns.find(c => c.primaryKey);
1464+
if (!primaryKeyColumn) continue;
1465+
const childRecords = await adminforth.resource(resource.resourceId).list([Filters.EQ(foreignKeyColumn.name, parentId)]);
1466+
for (const record of childRecords) {
1467+
const childId = record[primaryKeyColumn.name];
1468+
if (deleteStrategy === 'cascade') {
1469+
await handleCascadeOnDelete.call(this, resource, childId);
1470+
await adminforth.resource(resource.resourceId).delete(childId);
1471+
continue;
1472+
}
1473+
if (deleteStrategy === 'setNull') {
1474+
await adminforth.resource(resource.resourceId).update(childId, {[foreignKeyColumn.name]: null,});
1475+
}
1476+
}
1477+
}
1478+
}
14551479
server.endpoint({
14561480
method: 'POST',
14571481
path: '/delete_record',
@@ -1464,23 +1488,10 @@ export default class AdminForthRestAPI implements IAdminForthRestAPI {
14641488
if (!record){
14651489
return { error: `Record with ${body['primaryKey']} not found` };
14661490
}
1467-
if (resource.options.allowedActions.delete === false) {
1491+
if (!resource.options.allowedActions.delete) {
14681492
return { error: `Resource '${resource.resourceId}' does not allow delete action` };
14691493
}
1470-
1471-
const { allowedActions } = await interpretResource(
1472-
adminUser,
1473-
resource,
1474-
{ requestBody: body, record: record },
1475-
ActionCheckSource.DeleteRequest,
1476-
this.adminforth
1477-
);
1478-
1479-
const { allowed, error } = checkAccess(AllowedActionsEnum.delete, allowedActions);
1480-
if (!allowed) {
1481-
return { error };
1482-
}
1483-
1494+
await handleCascadeOnDelete.call(this, resource, body['primaryKey']);
14841495
const { error: deleteError } = await this.adminforth.deleteResourceRecord({
14851496
resource, record, adminUser, recordId: body['primaryKey'], response,
14861497
extra: { body, query, headers, cookies, requestUrl, response }

0 commit comments

Comments
 (0)