Check for existing children behaviour
CakePHP, Development, Frameworks, Labs, PHP October 23rd, 2007
In some of my projects I had a requirement to prevent deletion of the records, which had children. That’s why I create a small behaviour which checks these cases and prevent this.
Add this code in /app/models/behaviours/has_children.php
/**
* Prevent deletion if child record found
*
* @author Nik Chankov
* @url http://nik.chankov.net
*/
class HasChildrenBehavior extends ModelBehavior {
/**
* Empty Setup Function
*/
function setup(&$model) {
$this->model = $model;
}
/**
* Run the check and cancel the deletion if child is found
* @access public
*/
function beforeDelete(){
if(isset($this->model->hasMany)){
foreach($this->model->hasMany as $key=>$value){
$childRecords = $this->model->{$key}->findAll(array($value['foreignKey']=>$this->model->id));
if(count($childRecords) > 0){
return false;
}
}
}
return false;
}
}
?>
What that code doing? In the function beforeDelete check all models in the hasMany array /defined in your model/ and check if there are records related to the current model. if there is any return false, if there are none - return true which will continue deletion.
How to activate it?
if you want this behaviour to be valid for all models in your application, just add it in AppModel class with:
Or if you want only few models to be affected, just put this $actsAs only in them.
Now it will work, but unfortunately when we do Delete the normal code (generated from the /console/cake) in that action is something like:
...
function delete($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid id for Category', true));
$this->redirect(array('action'=>'index'), null, true);
}
if ($this->MyModel->del($id)) {
$this->Session->setFlash(__('MyModel #', true).$id.__(' deleted', true));
$this->redirect(array('action'=>'index'), null, true);
}
}
...
?>
Which when receive “return false” wont enter in the second if and the page will remain blank. To prevent such issue your delete actions should look like:
...
function delete($id = null) {
if (!$id) {
$this->Session->setFlash(__('Invalid id for Category', true));
$this->redirect(array('action'=>'index'), null, true);
}
if ($this->MyModel->del($id)) {
$this->Session->setFlash(__('MyModel #', true).$id.__(' deleted', true));
$this->redirect(array('action'=>'index'), null, true);
} else {
$this->Session->setFlash(__(' The record cannot be deleted!', true));
$this->redirect(array('action'=>'index'), null, true);
}
}
...
?>
The inconvenience coming from that, because you should make this in all of your controllers, but if you starting a new project and you modify your templates before start baking it shouldn’t be so big pain.
Add to:


Leave a Comment