tags:

views:

110

answers:

1

I'm trying to execute some logic before deleting a field. I have some models that are dependent on the model being deleted, and I want to make sure that image files related to those dependent models are also deleted, but I'm a bit confused on how the model callbacks work.

I know that I define the before Delete function in the model class, but How do I access the data in the current model or dependent models being deleted?

function beforeDelete() {

}

I'm just a little confused as how to use these callbacks, and I haven't seen any great documentation out there.

Edit: After adding this to the parent model, it seems to always return false.

function beforeDelete() {
    if ($this->DependentModel->find('count', array('conditions' => array('DependentModel.parent_id' => $this->id))) == 1){  
        return true;
    } else{
        return false;
    }
}

Should be obvious what I'm trying to do here. If there is one entry of the dependent model present in the table, return true and continue the deletion. I made sure that there is in fact one table entry that is dependent on the object being deleted. When I execute the delete action it always returns false. What's going on here?

+4  A: 

When using callbacks, you can refer to the API for the class you are extending to check the parameters it accepts. Your implementation should accept, at minimum, the same parameters as the methods you are overriding.

For example, Model::beforeDelete is implemented like so:

/**
 * Called before every deletion operation.
 *
 * @param boolean $cascade If true records that depend on this record will also be deleted
 * @return boolean True if the operation should continue, false if it should abort
 * @access public
 * @link http://book.cakephp.org/view/1048/Callback-Methods#beforeDelete-1054
 */
function beforeDelete($cascade = true) {
    return true;
}

And also, ModelBehavior::beforeDelete is implemented like this (ie. when making a behavior):

/**
 * Before delete callback
 *
 * @param object $model Model using this behavior
 * @param boolean $cascade If true records that depend on this record will also be deleted
 * @return boolean True if the operation should continue, false if it should abort
 * @access public
 */
function beforeDelete(&$model, $cascade = true) { }

Next, it is useful to know that when saving to a model and passing in the controller's data (ie. $this->data in the controller) that data is set to the model (ie. $this->data in the model). [This happens during Model::save(), currently on line 1225.]

In the case of the first example you can access the model using $this and in the second example you can access the model using $model (as $this would be the behavior in that context). So to get at the data, you want to use $this->data or $model->data. You can also access that model's related models using chaining (ie. $this->RelatedModel or $model->RelatedModel).

As the docblock comments state, $cascade should let you know if this is a cascading delete that is happening (true by default) in case your code needs to take different actions when this is or isn't the case; and your implementation of the method should return false if you want to abort the save operation (otherwise, return true when you are done).

There is a Media plugin for CakePHP which implements this exact functionality that can be used as a reference.

deizel
Thanks so much, this is great info!
wcolbert
No problem. In reply to your edit, I tested your code at this end (on 1.3) and couldn't find a fault. It worked as expected, deleting only when there was a single dependent record. I would assign your `find('count')` call to a `$count` variable then `debug($count); die;` to determine if you are getting the expected return value.
deizel