I think it happens sometimes, that you need to keep a certain amount of data, and don't want your database table to grow out of limit.
For example, we have a fairly typical Post model and a posts table with more than 100 posts. We only want the latest 100 posts in the table, so we need to delete older posts on every new post.
To accomplish this in Cake way, we need to write a bit of script. So, let's add a trimming method to our Post model (You can also add it to AppModel to make it reusable in other models):
<?php
class Post extends AppModel {
var $name = 'Post';
function trim($options) {
$defaults = array('conditions' => null, 'maintain' => null, 'order' => null, 'cascade' => true, 'callbacks' => false, 'notices' => true);
$options = array_merge($defaults, (array)$options);
extract($options);
if ($notices) {
$calledFrom = debug_backtrace();
if ($calledFrom[1]['function'] != 'beforeSave') {
trigger_error(
__("({$this->alias}::trim()) should only be called by Model::beforeSave()", true),
E_USER_WARNING
);
return false;
}
}
$conditions = (array)$conditions;
$count = $this->find('count', array_merge(array('recursive' => -1), compact('conditions')));
if ($count <= 0) {
return false;
}
if (is_int($maintain) && $maintain > 0) {
$start = $maintain - 1;
$last = $count - $start;
unset($maintain);
if ($start == $last) {
return false;
}
}
if (isset($start) && isset($last) && $count > $start) {
if (is_null($order)) {
$order = array($this->alias . '.' . $this->primaryKey => 'desc');
}
$limit = $start . ',' . $last;
$ids = Set::extract(
$this->find('all', array_merge(array(
'fields' => "{$this->alias}.{$this->primaryKey}", 'recursive' => -1),
compact('conditions', 'order', 'limit')
)),
"{n}.{$this->alias}.{$this->primaryKey}"
);
$this->deleteAll(array($this->alias . '.' . $this->primaryKey => $ids), $cascade, $callbacks);
}
}
}
?>
In theory it's pretty simple.
Now, let's call it in our Post model beforeSave():
function beforeSave() {
$this->trim(array(
'maintain' => 100
));
return true;
}
Here are some options available for the trim() method.
$options has the following possible keys - all of which are optional except for the 'maintain' key:
conditions
mixed
Conditions to match
(no default)
maintain
integer
The maximum number of records to maintain
(no default)
order
mixed
String or array defining order
primary key desc
cascade
boolean
Set to true to delete records that depend on this record
true
callbacks
boolean
Run callbacks (not being used).
false
notices
boolean
When set to false, E_NOTICES wont't be displayed
true
That’s all folks.
