Relational integrity constraint

What is the best way to enforce relational integrity?
Example we have a page for products and a page for categories.
We do not want the panel users to delete a category that has products, first they need to delete the products of that category. Logic: If a category has 0 products we can delete the category.

I guess we can do this by creating a model for categories and override the default delete function? Is there some documentation on this? Thank you.

Documentation for what exactly?

Models: Page models | Kirby CMS

Examples for overwriting default method: https://getkirby.com/docs/guide/virtual-pages/content-from-database

The alternative would be a page.delete:before hook that throws an error when a user tries to delete a page that they are not supposed to delete.

1 Like

@texnixe Thank you. Just wanted to have this validated as it is something we will use a lot.

I’m interested in getting a bit more detail in this as I have a similiar use case as you @wdebusschere. Would you want to share your solution?

Optimally I would want to be able to provide a bit more detailed feedback to the panel user, like list the pages where the page has a relationship and perhaps give the option to continue anyway. But it seems the only way to communicate with the panel is to throw an error that is displayed inside the current dialog in red and prefixed with “Error” (I tried with using a hook).

@texnixe On a more general note, is it possible to trigger anything else but errors in the panel? I.e just display information with my own title and text. For example: I have a overwritten the update method in a page model that synchronizes some fields and attempts to auto publish. To see changes reflected in the panel the page needs to be reloaded. I want to display a message to the user like “Page is published! Reload”. The only way I seem to be able to do that is by throwing an exception. But the UX gets weird when the title of that dialog is “Form not saved” even when it is.

@TimKinali I’m going to program this in the next days, will keep you posted.

1 Like

There is no elegant solution, we just override the delete method and we have a getDocumentsCount function in the model.

    public function delete(bool $force = false): bool
    {
        $count = $this->getDocumentsCount();
        if ($count > 0) {
            throw new Error($count . ' related records (Documents) found.');             
        }
        else
        {
            return parent::delete();
        }
    }
1 Like