Solved thread

This post is marked as solved. If you think the information contained on this thread must be part of the official documentation, please contribute submitting a pull request to its repository.

How to make related models automatically cascade delete?

I have an Organizations model with many Sites models linked to it. I want to delete an Organizations model and have it cascade delete the site models. I added the "action" => Relation::ACTION_CASCADE, part because it was complaining with the message that there were existing Sites linked to the Organization. After I added this option it no longer complains but it is not actually deleting the related sites and its also not triggering the events. I can loop and delete all of the Sites and that works.

Also none of the afterDelete events are being triggered on any model.

    protected function initialize()
    {
        $this->addSoftDeleteBehavior('status');

        $this->hasMany('id', 'Project\Models\Sites', 'organizationsId', [
            'alias' => 'sites',
            'foreignKey' => [
                'action' => Relation::ACTION_CASCADE,
                'message' => 'Organization cannot be deleted because it has sites'
            ]
        ]);
    }


46.9k

Can someone confirm the afterDelete event works as advertised. That event doesn't seem to be called. Does it have something to do with the soft delete?



30.8k

Hi,

I'm not a guru with all these dbs stuff, but perhaps that problem come from the db design (maybe tell in db scema to cascade delete the related sites)



46.9k
edited Dec '14

Sure I could do that but then I won't get access to the programming hooks and I prefer to use a database transaction in PHP.



46.9k

I can put a Site delete loop in routine for deleting an Organization in a task, but that doesn't seem like the right place to put it.

Also, why are the afterDelete model events not firing?

    $this->db->begin();

        $sites = $org->getSites();
        foreach ($sites as $site) {
            if (!$site->delete()) {
                $this->db->rollback();
                $message = implode("\n", $org->getMessages());
                throw new \Exception("$message", 1);
            }
        }

        if (!$org->delete()) {
            $this->db->rollback();
            $message = implode("\n", $org->getMessages());
            throw new \Exception("$message", 1);
        }

        $this->db->commit();


46.9k
Accepted
answer

The model is setup with the SoftDelete behavior and this causes the delete operation to cancel.

Yes. To clarify more, when SoftDelete is set up on a model, afterUpdate gets called instead of afterDelete when deleting.