<?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>Promet CakePHP Source &#187; Associations</title>
	<atom:link href="http://cakephp.prometsupport.com/category/model/model-association/feed/" rel="self" type="application/rss+xml" />
	<link>http://cakephp.prometsupport.com</link>
	<description></description>
	<lastBuildDate>Mon, 23 Feb 2009 08:03:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Learn Containable Behavior by Example</title>
		<link>http://cakephp.prometsupport.com/2008/learn-containable-behavior-by-example/</link>
		<comments>http://cakephp.prometsupport.com/2008/learn-containable-behavior-by-example/#comments</comments>
		<pubDate>Thu, 18 Sep 2008 07:58:49 +0000</pubDate>
		<dc:creator>rachel</dc:creator>
				<category><![CDATA[Associations]]></category>
		<category><![CDATA[Behaviors]]></category>
		<category><![CDATA[CakePHP 1.2]]></category>
		<category><![CDATA[Model]]></category>
		<category><![CDATA[Tips & Tutorials]]></category>
		<category><![CDATA[containable]]></category>
		<category><![CDATA[optimization]]></category>

		<guid isPermaLink="false">http://cakephp.prometsupport.com/?p=44</guid>
		<description><![CDATA[In cakephp, adding relationships is easy. We just have to declare the hasOne, belongsTo, hasMany and the famous HABTM relationship to do all the dirty work of joining tables. But declaring them all at once could lead to a slow page. In version 1.1, what we do is utilize the bindModel() and unbindModel(). We do [...]]]></description>
			<content:encoded><![CDATA[<p>In cakephp, adding relationships is easy. We just have to declare the hasOne, belongsTo, hasMany and the famous HABTM relationship to do all the dirty work of joining tables. But declaring them all at once could lead to a slow page.</p>
<p>In version 1.1, what we do is utilize the <a href="http://cakephp.prometsupport.com/2008/binding-ur-models-d-easy-way/">bindModel() and unbindModel()</a>. We do not declare all associations in the Model class yet. This was a good solution. I was looking for this option in version 1.2 and I found the Containable Behavior. Studying containable was a little rough before but there are documents now that are really helpful.<br />
<span id="more-44"></span></p>
<ul>
<li><a href="http://book.cakephp.org/view/474/Containable">Cakephp Book: Containable</a></li>
<li><a href="http://cakebaker.42dh.com/2008/05/18/new-core-behavior-containable/">CakeBaker: New Core Behavior &#8211; Containable</a></li>
<li><a href="http://www.studiocanaria.com/articles/cakephp_containable_behavior">StudioCanaria: Cakephp Containable Behavior</a></li>
</ul>
<p>Today, I&#8217;ll be showing you how to use Containable in pagination and in regular find method. You must have a fair understanding of the behavior so I suggest you read the above articles first. If you are ready, follow the instructions below:</p>
<ol>
<li>Download the latest 1.2 release of cake. As of this writing, I tested it in cake_1.2.0.7296-rc2. Do the usual cake installation procedures.</li>
<li><a href="http://cakephp.prometsupport.com/wp-content/uploads/2008/09/containable_by_example.zip">Download this file</a> and unzip. It must contain an &#8220;app&#8221; folder</li>
<li>Replace the /app from #1 with the /app from #2 but leave the config file of #1.</li>
<li>Use the /app/class.sql to setup your database</li>
</ol>
<p>The idea of the sample is taken from a virtual school application. So we have Departments, Courses, Classes, Students and Teachers, Students Comments on Class and Students Ratings on Class. The following is an explanation of tables declared in class.sql so you can follow the relationships:</p>
<table style="border-collapse: collapse;" border="1" cellspacing="0" cellpadding="10" width="100%">
<tbody>
<tr valign="top">
<th width="20%">TABLE</th>
<th>RELATIONSHIP</th>
</tr>
<tr valign="top">
<td>department</td>
<td>has many courses</td>
</tr>
<tr valign="top">
<td>courses</td>
<td>has many classes<br />
belongsto departments</td>
</tr>
<tr valign="top">
<td>classes</td>
<td>belongs to courses<br />
belongs to teacher<br />
has many comments<br />
has many ratings</td>
</tr>
<tr valign="top">
<td>teachers</td>
<td>has many classes</td>
</tr>
<tr valign="top">
<td>ratings</td>
<td>belongs to class<br />
belongs to student</td>
</tr>
<tr valign="top">
<td>comments</td>
<td>belongs to class<br />
belongs to student</td>
</tr>
<tr valign="top">
<td>students</td>
<td>has many comments<br />
has many ratings</td>
</tr>
</tbody>
</table>
<h2>Exampe1: List of Classes</h2>
<p>What we will do is get only the basic information for the list of classes. Those includes:</p>
<ul>
<li>Class title</li>
<li>Course it belongs to</li>
<li>Department it belongs to</li>
<li>Teacher name</li>
</ul>
<p>It will look like this (replace the http://localhost with your local address)<br />

http://localhost/cake/my_classes/index</p>

<p>Let&#8217;s compare the recursive and containable method.</p>
<p><strong>Using The Recursive Method</strong><br />
Check the MyClassesController::unfiltered_result() for your reference. First try is I added the ffg line<br />
<code lang="php">$this->MyClass->recursive = 1; </code><br />
but the problem is that I could not get the Department name. Then I tried<br />
<code lang="php">$this->MyClass->recursive = 2; </code><br />
and there I have all the information I need. The problem is that there are just to many data I do not need. Another option is to use the the paginate fields filter. Try adding this:<br />
<code lang="php">$this->paginate['MyClass']['fields'] = array( 'Course.title', 'MyClass.title' );</code></p>
<p>The result? Check it for yourself in http://localhost/cake/my_classes/unfiltered_result</p>
<p><strong>Using Containable Behavior</strong><br />
If you look at MyClassesController::index2(), you would see the ffg:<br />
<code lang="php"><br />
        $this->paginate['MyClass']['contain'] = array (<br />
            'Teacher',<br />
            'Course' => array (<br />
                'Department' => array (<br />
                    'fields' => array (<br />
                        'Department.title',<br />
                        'Department.id'<br />
                    )<br />
                )<br />
            )<br />
        );<br />
</code><br />
That basically tells cake to find the Class Teacher and return all fields, the course it belongs to and return all the fields and finally the course&#8217; Department title and ID. Now run this http://localhost/cake/my_classes/filtered_result and compare the result with the previous example. It became cleaner isn&#8217;t it?</p>
<p>With Containable, you can specify which tables to include and what fields to include each table. You can also add order and limit filters and also conditions. It took me a while to grasp the format because at first glance it is a bit difficult to follow. I use the following format:</p>
<p><code lang="php"><br />
$this->Model0->contain( array(<br />
 'Model1' => array (<br />
 'fields' 	 => array( 'modelField1', 'modelField2' ),<br />
 'conditions' => array( 'your condition here' ),<br />
 'order' 	 => array( 'id' => 'asc' ),<br />
 ),<br />
 'Model2',<br />
 'Model2'<br />
 )<br />
)<br />
</code></p>
<h2>Example2: Class View</h2>
<p>This is just to show you a more complicated containable query. We want to get more information about the class. That includes:</p>
<ul>
<li>Class title</li>
<li>Course it belongs to</li>
<li>Department it belongs to</li>
<li>Teacher name</li>
<li><strong>Student comments that were approved and student name</strong></li>
<li><strong>Student ratings that were approved and student name</strong></li>
</ul>
<p>We can achieve the desired results using recursive but then again we will be wasting so much process time. In containable, we&#8217;ll just have to declare what we want.</p>
<p><code lang="php"><br />
        $this->MyClass->contain( array(<br />
            'Teacher',<br />
            'Rating'     => array(<br />
                'Student',<br />
                'order' => array( 'created' => 'desc' ),<br />
                'conditions' => array( 'approved' => 1 )<br />
            ),<br />
            'Comment'    => array(<br />
                'Student',<br />
                'order' => array( 'RAND()' ),<br />
                'limit' => 3 ,<br />
                'conditions' => array( 'approved' => 1 )<br />
            ),<br />
            'Course'     => array(<br />
                'Department' => array(<br />
                    'fields' => array(<br />
                        'Department.title',<br />
                        'Department.id'<br />
                    )<br />
                )<br />
            )<br />
            )<br />
        );<br />
</code></p>
<p>Can you see the format now? Play around with the codes and check their results to get more comfortable with it. Happy Baking!</p>
]]></content:encoded>
			<wfw:commentRss>http://cakephp.prometsupport.com/2008/learn-containable-behavior-by-example/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Binding your Models the Easy Way</title>
		<link>http://cakephp.prometsupport.com/2008/binding-ur-models-d-easy-way/</link>
		<comments>http://cakephp.prometsupport.com/2008/binding-ur-models-d-easy-way/#comments</comments>
		<pubDate>Wed, 16 Jan 2008 02:39:44 +0000</pubDate>
		<dc:creator>carol</dc:creator>
				<category><![CDATA[Associations]]></category>
		<category><![CDATA[CakePHP 1.1]]></category>
		<category><![CDATA[Model]]></category>
		<category><![CDATA[Tips & Tutorials]]></category>
		<category><![CDATA[bindModel]]></category>
		<category><![CDATA[unbindModel]]></category>

		<guid isPermaLink="false">http://cakephp.prometsupport.com/2008/01/15/my-piece-of-cakefinally/</guid>
		<description><![CDATA[Finally, I&#8217;ve posted my first cakephp blog which is already a week late. So late that I really had a hard time picking a nice topic to make it worth the wait. I don&#8217;t know if this one is but I hope it&#8217;ll be helpful especially to those who are new to cake. Ive been [...]]]></description>
			<content:encoded><![CDATA[<p>    Finally, I&#8217;ve posted my first cakephp blog which is already a week late. So late that I really had a hard time picking a  nice topic to make it worth the wait.  I don&#8217;t know if this one is but I hope it&#8217;ll be helpful especially to those who are new to cake.  Ive been working on <a href="http://isupportthismessage.com">IsupportThisMessage.com</a> for almost a year and still supporting it until now since they&#8217;re planning to add more functionalities to the system. This is where I learned the basics of cake.The <a href="http://manual.cakephp.org">manual</a> is quite simple and I&#8217;ve read it over and over. But when I thought I already know a lot and started coding,  I realized, I don&#8217;t even know a bit. So really, there&#8217;s no better way of learning than actually applying it. And for almost a year, I&#8217;ve learned a lot but I must admit, I still have a lot to learn.</p>
<p>One nice thing I like about cake is the use of <a href="http://www.enode.com/x/markup/tutorial/mvc.html">MVC pattern</a> which makes my codes more organized. And I like how the querying is done which is made more simple because you wouldn&#8217;t need to declare associated tables within your query if you have already specified the associations within your model.  Fantastic!  One of the most powerful features of CakePHP is the relational       mapping provided by the model.  At first, I didn&#8217;t want to touch anything in the models coz I was confused about associations. Besides I was scared I might break the code. But when I finally understood how, I declared the necessary associations within my models most especially &#8220;messages&#8221;, coz in isupport this is often being used and it has a lot of associated tables in it. But sometimes, when you query, your association settings in the model file are giving you too much       (or not enough) information. What I mean to say is, sometimes you wouldn&#8217;t need some of the associated tables in your query result. So you have to think of a way how to minimize the result, and that is where <strong>unbindModel</strong> &amp; <strong>bindModel</strong>  model functions are used which allow you to change your association settings on the fly. But as quoted from the <a href="http://bakery.cakephp.org/articles/view/keeping-bindmodel-and-unbindmodel-out-of-your-controllers">bakery section of cakephp.org by TommyO</a>,</p>
<blockquote><p>Changing the requirements of a bind done in this way means going through your controllers and changing the bindModel call, often in multiple places. Using unbindModel in a controller also means every time a new association is added you may need to go back into your controllers and unbind the new associations in order to optimize your code.</p></blockquote>
<p>Silly, but true. Thanks to TommyO, he created a method to simplify this using the approach:</p>
<blockquote><p>binding to other Models only when needed or unbinding existing relations to minimize the size of your result set.</p></blockquote>
<p>But just an overview, you would just need to add a function within your appmodel. Then in your model class, just define your associations within an array called $assoc. You will see an example from the link. So easy huh?</p>
<p>So in your controller:</p>
<p><code><span style="color: #000000"> <span style="color: #0000bb">&lt;?php<br />
MessageController </span><span style="color: #007700">extends </span><span style="color: #0000bb">AppController </span><span style="color: #007700">{<br />
function index(</span><span style="color: #0000bb">$id</span><span style="color: #007700">) {<br />
</span><span style="color: #ff8000">// establish necessary associations<br />
</span><span style="color: #0000bb">$this</span><span style="color: #007700">-&gt;Message</span><span style="color: #0000bb"></span><span style="color: #007700">-&gt;</span><span style="color: #0000bb">expects</span><span style="color: #007700">(array(</span><span style="color: #dd0000">'Comments'</span><span style="color: #007700">, </span><span style="color: #dd0000">'User'</span><span style="color: #007700">));<br />
</span><span style="color: #0000bb"></span><span style="color: #007700"></span><span style="color: #0000bb">$results </span><span style="color: #007700">= </span><span style="color: #0000bb">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000bb">Message</span><span style="color: #007700">-&gt;</span><span style="color: #0000bb">findAll</span><span style="color: #007700">(</span><span style="color: #0000bb"></span><span style="color: #007700"></span><span style="color: #0000bb"></span><span style="color: #007700">);<br />
}<br />
}<br />
</span><span style="color: #0000bb">?&gt;</span>  </span> </code></p>
<p>Now you have it. But that&#8217;s not all. Ive read <a href="http://bakery.cakephp.org/articles/view/an-improvement-to-unbindmodel-on-model-side">another post in the bakery related to TommyO&#8217;s method</a> for model associations. In TommyO&#8217;s approach, there&#8217;s a slight difference on the way you define your model association and the models get loaded *when* you call the <i>expects()</i> function. According to Mariano, the author of the post, he said he&#8217;s not a fan of changing how things are done in cakephp, neither do I. His approach is to use the Cakephp way of defining associations in the models and then specify which relations he&#8217;s interested in getting back when querying a model. This way, models behave the way models are supposed to. The main idea here is that you define your associations in the model the cakephp way. Then in your controller, if you want the standard result cakephp brings then you don&#8217;t need to call <i>expects()</i> (With TommyO&#8217;s approach, you will need to call <i>expects()</i>  with all the necessary values). Use <i>expects()</i>, only when you want to limit the result of your query. And if you want to unbindAll just call <i>expects()</i> with no parameters. You will need to add three functions in your appmodel which you will find <a href="http://bakery.cakephp.org/articles/view/an-improvement-to-unbindmodel-on-model-side">here</a>. There are additional topics included here like &#8220;<em>making multiple expects in one call</em>&#8220;. And if I&#8217;m a little confusing in explaining, I think you can understand it better when you visit the links. hehehehe.</p>
<p>Good luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://cakephp.prometsupport.com/2008/binding-ur-models-d-easy-way/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
