Chapter 16: deleting an acronym with Foreign key

In chapter 16, when I try to delete an acronym via the web app, I got the following error:

[ ERROR ] PostgreSQLDiagnosticResponse.ri_ReportViolation: ERROR: update or delete on table “acronyms” violates foreign key constraint “acronym_category_acronymID_fkey” on table “acronym_category” (Logger+LogError.swift:17)
[ DEBUG ] Possible causes for PostgreSQLDiagnosticResponse.ri_ReportViolation: update or delete on table “acronyms” violates foreign key constraint “acronym_category_acronymID_fkey” on table “acronym_category” (Logger+LogError.swift:23)

I don’t see why there should be an error: there is a foreign key on the AcronymCategoryPivot both for acronym id and category id, but that should not prevent me for deleting an acronym, since categories and acronyms are siblings.
In the other way, it seems natural to prevent deleting categories that are still used in acronyms, but not prevent deleting acronyms that still have a category.
Do you have the same error? Do you think it’s justified?


I had the same error or rather, illogical behaviour, so I searched for a bit for ways to solve this issue and I think I came up with one. If I change the AcronymCategoryPivot’s migration to look like this (line 5 is important), I get much more reasonable behaviour:

extension AcronymCategoryPivot: Migration {
    static func prepare(on connection: PostgreSQLConnection) -> Future<Void> {
        return Database.create(self, on: connection) { builder in
            try addProperties(to: builder)
            try builder.addReference(from: \.acronymID, to: \, actions: .update)
            try builder.addReference(from: \.categoryID, to: \

During a few minutes of testing, it seemed that with this code, I can’t delete any category that has acronyms assigned to it, but I can freely delete acronyms that belong in a category (and the relevant entries in the pivot table would also get deleted).

1 Like

@freddyf there isn’t any support for cascade deletes at the moment. So you can’t delete it since a category pivot is relying on it. You need to delete all the category pivots before you can delete the acronym. Cascade delete would solve that but it’s waiting to be implemented I believe

I understand that, technically, a pivot is relying on the acronym I want to delete, but conceptually, if I want to delete an acronym, I don’t want to delete all categories linked to this acronym. That makes no sense.
On the other hand, if I want to delete a category, I don’t want to delete all the acronyms linked to this category either, I just want to remove the category.
So “update” looks like a good solution to me.

Actually, I’m not sure why the action is called .update because if you inspect the table Fluent creates, you can clearly see that CASCADE is the action Fluent picked.

@freddyf see the latest code for adding support for Cascade deletes in