<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JonnyReeves.co.uk &#187; countercache</title>
	<atom:link href="http://www.jonnyreeves.co.uk/tag/countercache/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jonnyreeves.co.uk</link>
	<description>Actionscript, Flash, PHP and stuff</description>
	<lastBuildDate>Mon, 19 Jul 2010 15:36:14 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>CakePHP, Using CounterCache to keep track of Comments</title>
		<link>http://www.jonnyreeves.co.uk/2008/05/cakephp-using-countercache-to-keep-track-of-comments/</link>
		<comments>http://www.jonnyreeves.co.uk/2008/05/cakephp-using-countercache-to-keep-track-of-comments/#comments</comments>
		<pubDate>Sat, 31 May 2008 18:59:06 +0000</pubDate>
		<dc:creator>Jonny</dc:creator>
				<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[countercache]]></category>

		<guid isPermaLink="false">http://www.jonnyreeves.co.uk/?p=35</guid>
		<description><![CDATA[CounterCache is one of the new Core Model Behaviors in CakePHP 1.2 and it&#8217;s an absolute life saver for working with hasMany relationships where you want to OrderBy one of the children.
The basic idea behind a CounterCache is to keep tabs on how &#8216;children&#8217; a specific model has, this is best explained in a quick [...]]]></description>
			<content:encoded><![CDATA[<p>CounterCache is one of the new Core Model Behaviors in CakePHP 1.2 and it&#8217;s an absolute life saver for working with hasMany relationships where you want to OrderBy one of the children.</p>
<p>The basic idea behind a CounterCache is to keep tabs on how &#8216;children&#8217; a specific model has, this is best explained in a quick snippet of CakePHP.  In the following example I am going to set up a simple relationship of Users and Comments, however, I want to add the condition that posts must be moderated first as indicated by a `moderated` Boolean field in the MySQL table.</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw1">CREATE</span> <span class="kw1">TABLE</span> <span class="kw1">IF</span> <span class="kw1">NOT</span> <span class="kw1">EXISTS</span> <span class="st0">`users`</span> <span class="br0">&#40;</span><br />
&nbsp; <span class="st0">`id`</span> int<span class="br0">&#40;</span><span class="nu0">11</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">AUTO_INCREMENT</span>,<br />
&nbsp; <span class="st0">`username`</span> varchar<span class="br0">&#40;</span><span class="nu0">50</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,<br />
&nbsp; <span class="st0">`comments_count`</span> int<span class="br0">&#40;</span><span class="nu0">11</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,<br />
&nbsp; <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> &nbsp;<span class="br0">&#40;</span><span class="st0">`id`</span><span class="br0">&#41;</span><br />
<span class="br0">&#41;</span> ENGINE=InnoDB <span class="kw1">DEFAULT</span> CHARSET=latin1;</p>
<p><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> <span class="kw1">IF</span> <span class="kw1">NOT</span> <span class="kw1">EXISTS</span> <span class="st0">`comments`</span> <span class="br0">&#40;</span><br />
&nbsp; <span class="st0">`id`</span> int<span class="br0">&#40;</span><span class="nu0">11</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">AUTO_INCREMENT</span>,<br />
&nbsp; <span class="st0">`user_id`</span> int<span class="br0">&#40;</span><span class="nu0">11</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,<br />
&nbsp; <span class="st0">`message`</span> text <span class="kw1">NOT</span> <span class="kw1">NULL</span>,<br />
&nbsp; <span class="st0">`moderated`</span> tinyint<span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">DEFAULT</span> <span class="st0">&#8216;0&#8242;</span>,<br />
&nbsp; <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> &nbsp;<span class="br0">&#40;</span><span class="st0">`id`</span><span class="br0">&#41;</span><br />
<span class="br0">&#41;</span> ENGINE=InnoDB <span class="kw1">DEFAULT</span> CHARSET=latin1;<br />
&nbsp;</div>
<h2>Users Model: <b>/app/models/user.php</b></h2>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="kw2">Class</span> User <span class="kw2">extends</span> AppModel <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$name</span> = <span class="st0">&#8216;User&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$hasMany</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;Comment&#8217;</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="kw2">?&gt;</span><br />
&nbsp;</div>
<h3>Comments Model: <b>/app/models/comment.php</b></h3>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="kw2">Class</span> Comment <span class="kw2">extends</span> AppModel <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$name</span> = <span class="st0">&#8216;Comment&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$actsAs</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;CounterCache&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$belongsTo</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a> <span class="br0">&#40;</span><span class="st0">&#8216;User&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a> <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;foreignKey&#8217;</span> =&gt; <span class="st0">&#8216;user_id&#8217;</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;counterCache&#8217;</span> =&gt; <span class="st0">&#8216;comments_count&#8217;</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;counterScope&#8217;</span> =&gt; <span class="st0">&#8216;moderated = 1&#8242;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="kw2">?&gt;</span><br />
&nbsp;</div>
<p>So the magic being introduced here is the CounterCache Behavior,  in the Comments Model (which is included by setting is in the $actsAs variable).  The <strong>&#8216;counterCache&#8217; => &#8216;comments_count&#8217;</strong> value indicates to column on the `belongsTo` table which will contain the count and the <strong>&#8216;counterScope&#8217; => &#8216;moderated = 1&#8242; </strong> tells CounterCache to only increment the count value when this SQL Condition is met (in this case, `moderated` must be true).</p>
<p>Go ahead, build the application, throw some scaffolding into the Controllers and watch in awe as the `comments_count` value increments each time you save a comment where $data['Comment']['moderated'] = 1.  Now, this is all well and good, but in the real world, users won&#8217;t be setting the moderated value, instead you will have a Controller action to approve comments which looks something like this:</p>
<div class="dean_ch" style="white-space: nowrap; overflow: scroll;">
<span class="kw2">&lt;?php</span><br />
<span class="kw2">Class</span> Comment <span class="kw2">extends</span> AppModel <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$name</span> = <span class="st0">&#8216;Comment&#8217;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$actsAs</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;CounterCache&#8217;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> <span class="re0">$belongsTo</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a> <span class="br0">&#40;</span><span class="st0">&#8216;User&#8217;</span> =&gt; <a href="http://www.php.net/array"><span class="kw3">array</span></a> <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;foreignKey&#8217;</span> =&gt; <span class="st0">&#8216;user_id&#8217;</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;counterCache&#8217;</span> =&gt; <span class="st0">&#8216;comments_count&#8217;</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#8216;counterScope&#8217;</span> =&gt; <span class="st0">&#8216;moderated = 1&#8242;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="coMULTI">/**<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* Callback for when Cake has performed a save() operation.<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @param Boolean $created TRUE if save() performed a CREATE<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;* @return Void<br />
&nbsp; &nbsp; &nbsp; &nbsp; */</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span> afterSave<span class="br0">&#40;</span><span class="re0">$created</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>!<span class="re0">$created</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Kick the counterCache value.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$this</span>-&gt;<span class="me1">updateCounterCache</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<span class="kw2">?&gt;</span><br />
&nbsp;</div>
<p>You could further tweak this callback to enhance performance, only updating the counterCache when logic dictates it necessary.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonnyreeves.co.uk/2008/05/cakephp-using-countercache-to-keep-track-of-comments/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
