Skip to content

feat: implement cascading deletion for related records in delete #488

Open
kulikp1 wants to merge 12 commits intomainfrom
feature/AdminForth/1256/cascading-deletion-
Open

feat: implement cascading deletion for related records in delete #488
kulikp1 wants to merge 12 commits intomainfrom
feature/AdminForth/1256/cascading-deletion-

Conversation

@kulikp1
Copy link
Collaborator

@kulikp1 kulikp1 commented Feb 25, 2026

…oint

return { error };
}

await handleCascadeOnDelete.call(this, resource, body['primaryKey']);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (resource.foreignResource.onDelete) {
if (resource.foreignResource.onDelete === "cascade") {
await adminforth.resource(resource.resourceId).delete(childId);

} else if (resource.foreignResource.onDelete === "setNull") {
await adminforth.resource(resource.resourceId).update(childId, {[foreignKeyColumn.name]: null,});
}
}

return { error: `Resource '${resource.resourceId}' does not allow delete action` };
}

for (const childRes of this.adminforth.config.resources) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, where is the "if" which checks foreignResourcu.onDelete?
Also you have O(n)^3 complexity
This is bad practice to have loop inside loop inside loop

const childResources = this.adminforth.config.resources.filter(r => r.columns.some(c => c.foreignResource?.resourceId === resource.resourceId));
if (childResources.length){
for (const childRes of childResources) {
const foreignKeyColumn = childRes.columns.find(c => c.foreignResource?.resourceId === resource.resourceId);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why foreignKey? And also add check if we have onDelete property or not
Maybe better i think in the end move it to separate function

await this.adminforth.resource(childRes.resourceId).update(childRecord.id, {[foreignResourceColumn.name]: null});
}
} else {
return { error: `Wrong onDelete strategy: ${onDeleteStrategy}` };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove it, we have to throw error earlier in configValidator.
If user enters for example "cascdrvfv" we should throw error on the start of app and suggest him use cascade or setNull

}
}

if (col.foreignResource){
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You already have this check below
you can add your validation below
Also you can merge your two checks in one
like
if i have onDelete and onDelete is not cascade or setNull
throw error

if (col.foreignResource){
if (col.foreignResource.onDelete){
if (col.foreignResource.onDelete !== 'cascade' && col.foreignResource.onDelete !== 'setNull'){
errors.push (`Wrong delete strategy you can use 'onDelete' or 'cascade'`);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mistake in message you have setNull and cascade strategies but your error message tells that you have onDelete or cascade

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants