4

I'm after some code advice. I've got two models which are dependent on each other. When one of the models gets deleted I want to make sure both records in the database are deleted.

I handle this in one direction using foreign keys so if the parent gets deleted to. But as these rows are both dependent on each other I need the same functionality to happen in the child.

In the child model I've overloaded the delete method so it looks like this:

    public function delete() {

    $cameraTransaction = $this->dbConnection->beginTransaction();

    try
    {
        $this->ftpuser->delete();
        if($this->beforeDelete())
        {
            $result=$this->deleteByPk($this->getPrimaryKey())>0;
            $this->afterDelete();
        }
        $cameraTransaction->commit();
    }
    catch(Exception $e) // an exception is raised if a query fails
    {
        $cameraTransaction->rollBack();
    }

}

I've tested and this seems to work well. I wondered if an expert / guru could confirm whether I've done the right thing :)

Thanks

Alan

Alan Hollis
  • 1,292
  • 3
  • 14
  • 29
  • I think it would be better to do this at a database level. Could you not (assuming you're using MySQL) create a relation between the two tables and `ON DELETE CASCADE`? – Stu Oct 09 '12 at 14:00
  • you can use "ON DELETE CASCADE" but before this please read this link http://stackoverflow.com/questions/278392/should-i-use-the-cascade-delete-rule – Onkar Janwa Oct 09 '12 at 14:14
  • Sorry should have been clearer in the question. I used DELETE cascade but this only works from the Parent -> Child not when the child is deleted. – Alan Hollis Oct 09 '12 at 15:59

1 Answers1

2

I think you are doing it right. You can make it something more general.

Every model has relations defined, make some(or all) the relations deletable. You have to flag them ( in someway) deletable along with current record.

I would define a new function besides relations() in the model.

function deletableRelations() {
    return array('ftpuser', 'childs', .....);
}

and define some generic function (please include DB transactions in this function.)

function DeleteRelationships($model) {
    foreach( $model->deletableRelations() as $relation ) {
        if( $model->$relation == null) continue;

        if( is_array($model->$relation)) {
            foreach( $model->$relation as $relRecord ) {
                $relRecord->delete();
            }
        }
        else {
            $model->$relation->delete();
        }
    }
}

And this generic function can be used any of your models. Make sure that recursion does not happen here (i.e. parent deletes child ... but child also tries to delete parent. )

SuVeRa
  • 2,784
  • 2
  • 20
  • 27
  • 1
    Think about making a single request to delete associated record to avoid making lot of `"DELETE FROM ... WHERE id=.."` – Leto Apr 05 '13 at 09:55