A little tip about counterScope
One of many cool CakePHP’s features is the Counter Cache.
From the manual: “This function helps you cache the count of related data. Instead of counting the records manually via find(‘count’), the model itself tracks any addition/deleting towards the associated $hasMany model and increases/decreases a dedicated integer field within the parent model table.”
So if you have Forum with Posts, you can keep track of how many posts are there in a given forum by tracking this data in the “forums” table, which certainly speeds things up and takes a little load off your DB.
One feature that is not (yet) very well documented is the ability to provide a counterScope. It essentially allows you to specify a simple condition, which tells the model when to update (or when not to, depending on how you look at it) the counter value.
Using our Post model example, we can specify it like so:
class Post extends AppModel {
var $name = 'Post';
var $belongsTo = array('Forum'=>array(
'counterCache'=>true,
'counterScope'=>array('Post.deleted'=>0)));
}
This means that counter will only be updated for posts that are active: 'deleted'=>0.
Also, it is implied in this example that you have some admin tool, which lets you do soft deletes of your posts (i.e. set the “deleted” field to 1)…
Something simple, like this:
function delete($id = null) {
if($id) {
$this->Post->id = $id;
$this->Post->saveField('deleted', 1);
}
}
Guess what? Cake is going to update your counter field in the forums table, when you deactivate a post in this manner.
Brilliant stuff, I tell ya…
This is nice, didn’t know about that. So essentially this would update Post_count, in the Forums table so you can just simply get the total number of posts from one field.
@TG
Exactly. No need to query multiple tables.
Hey, nice post. You know what would be awesome? Adding this info to the book ;-). If you don’t, the Easter Bunny wont bring you any chocolates. EVAR.
@Joel Perras
I can’t let that happen can I?
The additional info has been submitted to the book ;)
The name of the field is lowercase and underscored, just like the convention for the model filenames.
Example-
Relationship: CartItem belongsTo Cart
Updated column: `Cart`.`cart_item_count`
…now if I could just get CounterCache to work on self-joined tables I’d be in exquisite harmony. Good tip though, teknoid. I wasn’t *entirely* sure what counterScope did – as you said, it wasn’t documented very well (and I couldn’t figure it out from the code; though to be honest I wasn’t looking very hard – I didn’t need it at the time). Thanks for documenting that!
@n8manAfter
Indeed, I thought that was in the manual…
@Brendon Kozlowski
No problemo ;)
@teknoid
My post should have been @ TG. It was mostly a correction but also a clarification.
Thanks for the info btw. I had no idea this existed. You teach me new things with practically every post.
@n8manAfter
Oh, gotcha.
Well, good to hear ;)
[...] A little tip about counterScope [...]
[...] Read more from the original source: A little tip about counterScope [...]
[...] How to make the counting of records faster without using SQL COUNT keyword in CakePHP using counterScope I found a site that explains how to use counterScope in CakePHP. Click here [...]