Deleting Data
- class
Cake\ORM\
Table
Once you’ve loaded an entity you can delete it by calling the originatingtable’s delete method:
- // In a controller.
- $entity = $this->Articles->get(2);
- $result = $this->Articles->delete($entity);
When deleting entities a few things happen:
- The delete rules will be applied. If the rulesfail, deletion will be prevented.
- The
Model.beforeDelete
event is triggered. If this event is stopped, thedelete will be aborted and the event’s result will be returned. - The entity will be deleted.
- All dependent associations will be deleted. If associations are being deletedas entities, additional events will be dispatched.
- Any junction table records for BelongsToMany associations will be removed.
- The
Model.afterDelete
event will be triggered.By default all deletes happen within a transaction. You can disable thetransaction with the atomic option:
- $result = $this->Articles->delete($entity, ['atomic' => false]);
The $options
parameter supports the following options:
atomic
Defaults to true. When true the deletion happens withina transaction.checkRules
Defaults to true. Check deletion rules before deletingrecords.
Cascading Deletes
When deleting entities, associated data can also be deleted. If your HasOne andHasMany associations are configured as dependent
, delete operations will‘cascade’ to those entities as well. By default entities in associated tablesare removed using Cake\ORM\Table::deleteAll()
. You can elect tohave the ORM load related entities, and delete them individually by setting thecascadeCallbacks
option to true
. A sample HasMany association with boththese options enabled would be:
- // In a Table's initialize method.
- $this->hasMany('Comments', [
- 'dependent' => true,
- 'cascadeCallbacks' => true,
- ]);
Note
Setting cascadeCallbacks
to true
, results in considerably slower deleteswhen compared to bulk deletes. The cascadeCallbacks option should only beenabled when your application has important work handled by event listeners.
Bulk Deletes
If you have an array of entities you want to delete you can use deleteMany()
to delete them in a single transaction:
- // Get a boolean indicating success
- $success = $this->Articles->deleteMany($entities);
- // Will throw a PersistenceFailedException if any entity cannot be deleted.
- $this->Articles->deleteManyOrFail($entities);
The $options
for these methods are the same as delete()
. Deletingrecords with these method will trigger events.
There may be times when deleting rows one by one is not efficient or useful.In these cases it is more performant to use a bulk-delete to remove many rows atonce:
- // Delete all the spam
- function destroySpam()
- {
- return $this->deleteAll(['is_spam' => true]);
- }
A bulk-delete will be considered successful if 1 or more rows are deleted. Thefunction returns the number of deleted records as an integer.
Warning
deleteAll will not trigger beforeDelete/afterDelete events. If you need thosefirst load a collection of records and delete them.
Strict Deletes
Using this method will throw anCake\ORM\Exception\PersistenceFailedException
if :
- the entity is new
- the entity has no primary key value
- application rules checks failed
- the delete was aborted by a callback.
If you want to track down the entity that failed to save, you can use theCake\ORMException\PersistenceFailedException::getEntity()
method:
- try {
- $table->deleteOrFail($entity);
- } catch (\Cake\ORM\Exception\PersistenceFailedException $e) {
- echo $e->getEntity();
- }
As this internally performs a Cake\ORM\Table::delete()
call, allcorresponding delete events will be triggered.