<?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>cakebaker &#187; model</title>
	<atom:link href="http://cakebaker.42dh.com/tags/model/feed/" rel="self" type="application/rss+xml" />
	<link>http://cakebaker.42dh.com</link>
	<description>baking cakes with CakePHP</description>
	<lastBuildDate>Tue, 20 Dec 2011 15:29:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>The Model::validates() trap</title>
		<link>http://cakebaker.42dh.com/2008/11/05/the-modelvalidates-trap/</link>
		<comments>http://cakebaker.42dh.com/2008/11/05/the-modelvalidates-trap/#comments</comments>
		<pubDate>Wed, 05 Nov 2008 09:56:29 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[validation]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=928</guid>
		<description><![CDATA[One mistake I make from time to time is to try to validate my data in the following way: public function example() { $data = array('Project' =&#62; array('name' =&#62; 'Testproject')); if ($this-&#62;Project-&#62;validates($data)) { echo 'valid'; } else { echo 'invalid'; } } If you look at this snippet, it probably looks fine to you. And [...]]]></description>
			<content:encoded><![CDATA[<p>One mistake I make from time to time is to try to validate my data in the following way:</p>
<pre>
<code>public function example() {
    $data = array('Project' =&gt; array('name' =&gt; 'Testproject'));
    if ($this-&gt;Project-&gt;validates($data)) {
        echo 'valid';
    } else {
        echo 'invalid';
    }
}</code>
</pre>
<p>If you look at this snippet, it probably looks fine to you. And it is fine if you are using CakePHP 1.1. Unfortunately, in CakePHP 1.2 the behavior of this method has changed, and so the example above doesn&#8217;t work as you would expect (depending on the validation rules). For a while the parameter of Model::validates() was deprecated (see <a href="http://cakebaker.42dh.com/2007/01/06/parameter-for-modelvalidates-is-now-deprecated/">Parameter for Model::validates() is now deprecated</a>) and caused a warning if you used it. In the meantime the parameter is back with a new meaning&#8230;</p>
<p>Compare the API docs for the validates() methods. First the CakePHP 1.1 <a href="http://api.cakephp.org/1.1/class_model.html#16c08a6787a40c74393c28f048ae2f31">docs</a>:</p>
<pre>
<code>/**
 * Returns true if all fields pass validation, otherwise false.
 *
 * @param array $data POST data
 * @return boolean True if there are no errors
 * @access public
 */</code>
</pre>
<p>And now the <a href="http://api.cakephp.org/class_model.html#edac6ae5521be420df41894851ba1970">docs</a> for CakePHP 1.2:</p>
<pre>
<code>/**
 * Returns true if all fields pass validation.
 *
 * @param string $options An optional array of custom options to be made available in the beforeValidate callback
 * @return boolean True if there are no errors
 * @access public
 * @link http://book.cakephp.org/view/410/Validating-Data-from-the-Controller
 */</code>
</pre>
<p>The parameter of the method is no longer for the data you want to validate but for options for the beforeValidate() callback method. So the example from the beginning has to be changed in the following way to make it work as expected:</p>
<pre>
<code>public function example() {
    $data = array('Project' =&gt; array('name' =&gt; 'Testproject'));
    $this-&gt;Project-&gt;create($data);
    if ($this-&gt;Project-&gt;validates()) {
        echo 'valid';
    } else {
        echo 'invalid';
    }
}</code>
</pre>
<p>Happy baking :)</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/11/05/the-modelvalidates-trap/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>An alternative way to define custom find types</title>
		<link>http://cakebaker.42dh.com/2008/09/23/an-alternative-way-to-define-custom-find-types/</link>
		<comments>http://cakebaker.42dh.com/2008/09/23/an-alternative-way-to-define-custom-find-types/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 12:22:11 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[model]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=848</guid>
		<description><![CDATA[Since changeset 7640 an alternative way for defining custom find types is possible. Rafael Bandeira already mentioned this approach around one month ago, only, at that time it was a hack because it violated the (visibility) conventions of CakePHP&#8230; In the meantime the visibility of this private functionality has been changed to protected, i.e. it [...]]]></description>
			<content:encoded><![CDATA[<p>Since <a href="https://trac.cakephp.org/changeset/7640">changeset 7640</a> an alternative way for defining custom find types is possible. <a href="http://rafaelbandeira3.wordpress.com">Rafael Bandeira</a> already <a href="http://rafaelbandeira3.wordpress.com/2008/08/28/the-new-way-to-define-find-methods/">mentioned</a> this approach around one month ago, only, at that time it was a hack because it violated the (visibility) conventions of CakePHP&#8230;</p>
<p>In the meantime the visibility of this private functionality has been changed to protected, i.e. it is now possible to access it from your own models. </p>
<p>Ok, let&#8217;s have a look at some code. We will define a &#8220;recent&#8221; find type for the Post model: </p>
<pre>
<code>class Post extends AppModel {	
    public function __construct($id = false, $table = null, $ds = null) {
        $this-&gt;_findMethods = $this-&gt;_findMethods + array('recent' =&gt; true);
        parent::__construct($id, $table, $ds);
    }

    protected function _findRecent($state, $query, $results = array()) {
        if ($state == 'before') {
            $query['order'] = 'Post.created DESC';
            $query['limit'] = 10;
            return $query;
        } else {
            return $results;
        }
    }
}</code>
</pre>
<p>First, we have to enable our custom find type in the constructor. I don&#8217;t know why you have to do that, because a disabled find type doesn&#8217;t make much sense to me&#8230;</p>
<p>The next step is to implement a protected method for our find type. The name of this method must start with &#8220;_find&#8221;, followed by the name of the find type (with the first character uppercased). It is a bit a special method, as it gets called twice per find operation: before the find is performed, and after it is performed. This also explains the first parameter, $state, which is either &#8220;before&#8221; or &#8220;after&#8221;. In the &#8220;before&#8221; state you have to prepare and return the query settings (which are passed in with the $query parameter), and in the &#8220;after&#8221; state you have the possibility to modify the results from the $results parameter. </p>
<p>The last step is to actually use our custom find type as shown in the following examples:</p>
<pre>
<code>$this-&gt;Post-&gt;find('recent');
$this-&gt;Post-&gt;find('recent', array('conditions' =&gt; array('Post.published' =&gt; true)));</code>
</pre>
<p>I&#8217;m not sure whether this approach should be really used, as the approach with overriding the find() method seems to be easier (see my earlier article <a href="http://cakebaker.42dh.com/2008/03/23/defining-custom-find-types/">Defining custom find types</a>).</p>
<p>Anyway, happy baking :)</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/09/23/an-alternative-way-to-define-custom-find-types/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Using a table without corresponding model</title>
		<link>http://cakebaker.42dh.com/2008/09/18/using-a-table-without-corresponding-model/</link>
		<comments>http://cakebaker.42dh.com/2008/09/18/using-a-table-without-corresponding-model/#comments</comments>
		<pubDate>Thu, 18 Sep 2008 14:34:57 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[model]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=822</guid>
		<description><![CDATA[I don&#8217;t know if the following is of any practical use, I was just curious whether it is possible to use a table without creating a corresponding model class for it. And yes, it is possible. There are two possible ways: instantiating the Model class manually, or using the ClassRegistry. First the manual way, which [...]]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t know if the following is of any practical use, I was just curious whether it is possible to use a table without creating a corresponding model class for it. And yes, it is possible. </p>
<p>There are two possible ways: instantiating the Model class manually, or using the ClassRegistry. First the manual way, which requires a bit more work:</p>
<pre>
<code>class ExamplesController extends AppController {
    public $uses = array();
	
    public function index() {
        App::import('Core', 'Model');
        $this-&gt;Month = new Model(false, 'months');
        $this-&gt;Month-&gt;alias = 'Month';
        $this-&gt;set('months', $this-&gt;Month-&gt;find('all'));
    }
}</code>
</pre>
<p>In the example above we create an instance of the Model class which uses the &#8220;months&#8221; table (and we don&#8217;t set an ID, hence the &#8220;false&#8221; in the constructor). Then we have to specify the alias property (and not the name property as you may guess). Without defining this property, the result of the find statement would be as shown below (notice the &#8220;Model&#8221; key):</p>
<pre>
<code>Array
(
    [0] =&gt; Array
        (
            [Model] =&gt; Array
                (
                    [id] =&gt; 1
                    [name] =&gt; January
                )
        )
    ...
)</code>
</pre>
<p>The second approach uses the ClassRegistry to instantiate the Model class. The example from above can now be shortened to:</p>
<pre>
<code>class ExamplesController extends AppController {
    public $uses = array();
	
    public function index() {
        $this-&gt;Month = ClassRegistry::init(array('class' =&gt; 'Model', 'table' =&gt; 'months', 'alias' =&gt; 'Month'));
        $this-&gt;set('months', $this-&gt;Month-&gt;find('all'));
    }
}</code>
</pre>
<p>As I said at the beginning of this article, this was just an experiment, but maybe you come up with a practical use case for it ;-)</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/09/18/using-a-table-without-corresponding-model/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Pseudo models</title>
		<link>http://cakebaker.42dh.com/2008/09/11/pseudo-models/</link>
		<comments>http://cakebaker.42dh.com/2008/09/11/pseudo-models/#comments</comments>
		<pubDate>Thu, 11 Sep 2008 07:30:08 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[model]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=799</guid>
		<description><![CDATA[Sometimes you have some functionality which is on a conceptual level a model but doesn&#8217;t have anything in common with CakePHP&#8217;s models. An example for such a functionality could be the usage of an external API (there are different philosophies about where to place such functionality: some create components, others build a data source, and [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes you have some functionality which is on a conceptual level a model but doesn&#8217;t have anything in common with CakePHP&#8217;s models. An example for such a functionality could be the usage of an external API (there are different philosophies about where to place such functionality: some create components, others build a data source, and the rest puts it in the model or somewhere else). If you put it into the model, then the respective model looks like:</p>
<pre>
<code>// app/models/example.php
class Example extends AppModel {
    public $useTable = false;

    public function doSomething() {
        // use API XY
    }
}</code>
</pre>
<p>This works fine, the only disadvantage is that your model inherits a lot of functionality that&#8217;s of no use. To avoid that, I use in such a case what I call &#8220;pseudo models&#8221;: I place PHP classes which do not extend AppModel in the models directory. The example from above looks then like:</p>
<pre>
<code>// app/models/example.php
class Example {
    public function doSomething() {
        // use API XY
    }
}</code>
</pre>
<p>In the controller you can use this model like any other model (of course with the restriction that none of the methods/properties defined in AppModel and Model will be available):</p>
<pre>
<code>$this-&gt;Example-&gt;doSomething();</code>
</pre>
<p>Happy baking!</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/09/11/pseudo-models/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>findCount vs. hasAny</title>
		<link>http://cakebaker.42dh.com/2008/07/11/findcount-vs-hasany/</link>
		<comments>http://cakebaker.42dh.com/2008/07/11/findcount-vs-hasany/#comments</comments>
		<pubDate>Fri, 11 Jul 2008 14:10:40 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[model]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=622</guid>
		<description><![CDATA[While changing some code to make use of the new Containable behavior I noticed code snippets that looked like: // in a model method if ($this-&#62;findCount($conditions) &#62; 0) { // do something } If you look at this example you will realize that what the code tells us is slightly different from what the intention [...]]]></description>
			<content:encoded><![CDATA[<p>While changing some code to make use of the new <a href="http://book.cakephp.org/view/474/containable">Containable behavior</a> I noticed code snippets that looked like:</p>
<pre>
// in a model method
if ($this-&gt;findCount($conditions) &gt; 0) {
    // do something
}
</pre>
<p>If you look at this example you will realize that what the code tells us is slightly different from what the intention of the code is. The code tells us something like: &#8220;if the number of records that meet the conditions is greater than 0 then do something&#8221;. But what we really want to express is: &#8220;if there are any records that meet the conditions then do something&#8221;. </p>
<p>Fortunately, there exists the method Model::hasAny() for this purpose (it is not a new method, but for some reason we almost never used it), and by using this method we can simplify the example from above and make it more expressive:</p>
<pre>
// in a model method
if ($this-&gt;hasAny($conditions)) {
    // do something
}
</pre>
<p>Sure, it is only a detail, but it helps to make the code a little bit more expressive.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/07/11/findcount-vs-hasany/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Order by field</title>
		<link>http://cakebaker.42dh.com/2008/06/10/order-by-field/</link>
		<comments>http://cakebaker.42dh.com/2008/06/10/order-by-field/#comments</comments>
		<pubDate>Tue, 10 Jun 2008 17:09:33 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=613</guid>
		<description><![CDATA[Yesterday, Tarique Sani mentioned in a thread in the CakePHP Group &#8220;order by field&#8221;. I know &#8220;order by&#8221;, but I never heard about &#8220;order by field&#8221; (which seems to be MySQL-specific). Ok, let&#8217;s do some examples to learn more about it. We will use the following countries table: [1] =&#62; USA [2] =&#62; Germany [3] [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday, <a href="http://www.sanisoft.com/blog/author/tariquesani/">Tarique Sani</a> mentioned in a <a href="http://groups.google.com/group/cake-php/browse_thread/thread/dfdebc408aac8bc0/e99c0260204a8ec8">thread</a> in the CakePHP Group &#8220;order by field&#8221;. I know &#8220;order by&#8221;, but I never heard about &#8220;order by field&#8221; (which seems to be MySQL-specific). </p>
<p>Ok, let&#8217;s do some examples to learn more about it. We will use the following countries table:</p>
<pre>
[1] =&gt; USA
[2] =&gt; Germany
[3] =&gt; Russia
[4] =&gt; Austria
[5] =&gt; China
[6] =&gt; Switzerland
</pre>
<p>Now, we don&#8217;t want to sort them by the id, but by some &#8220;strange&#8221; order: Austria, USA, China, Russia, Switzerland, Germany. For this purpose we can use &#8220;order by field&#8221;: the first parameter is the column name and all following parameters are values of the respective column. In CakePHP it is done in the following way:</p>
<pre>
$this-&gt;Country-&gt;find('list', array('order' =&gt; array('FIELD(Country.id, 4, 1, 5, 3, 6, 2)')));
</pre>
<p>And we get the expected result:</p>
<pre>
[4] =&gt; Austria
[1] =&gt; USA
[5] =&gt; China
[3] =&gt; Russia
[6] =&gt; Switzerland
[2] =&gt; Germany
</pre>
<p>Probably more common is the scenario that you want to have certain values at the top of a list, and the other values of the list should be ordered alphabetically. If we want the German-speaking countries at the top of the list we would do:</p>
<pre>
$this-&gt;Country-&gt;find('list', array('order' =&gt; array('FIELD(Country.id, 2, 4, 6)', 'Country.name')));

or 

$this-&gt;Country-&gt;find('list', array('order' =&gt; array('FIELD(Country.name, "Germany", "Austria", "Switzerland")', 'Country.name')));
</pre>
<p>Unfortunately, this doesn&#8217;t return the expected result, the records which should be at the top are at the bottom:</p>
<pre>
[5] =&gt; China
[3] =&gt; Russia
[1] =&gt; USA
[2] =&gt; Germany
[4] =&gt; Austria
[6] =&gt; Switzerland
</pre>
<p>We can solve this &#8220;problem&#8221; by using the &#8220;DESC&#8221; keyword and changing the order of the provided values:</p>
<pre>
$this-&gt;Country-&gt;find('list', array('order' =&gt; array('FIELD(Country.id, 6, 4, 2) DESC', 'Country.name')));

or

$this-&gt;Country-&gt;find('list', array('order' =&gt; array('FIELD(Country.name, "Switzerland", "Austria", "Germany") DESC', 'Country.name')))
</pre>
<p>With those changes we get the expected result:</p>
<pre>
[2] =&gt; Germany
[4] =&gt; Austria
[6] =&gt; Switzerland
[5] =&gt; China
[3] =&gt; Russia
[1] =&gt; USA
</pre>
<p>Thanks to Tarique for mentioning &#8220;order by field&#8221; and to <a href="http://www.gigapromoters.com/blog/">Abhimanyu Grover</a> for asking the original question.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/06/10/order-by-field/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Validation of optional fields with multiple validation rules</title>
		<link>http://cakebaker.42dh.com/2008/05/24/validation-of-optional-fields-with-multiple-validation-rules/</link>
		<comments>http://cakebaker.42dh.com/2008/05/24/validation-of-optional-fields-with-multiple-validation-rules/#comments</comments>
		<pubDate>Sat, 24 May 2008 14:33:29 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[validation]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=606</guid>
		<description><![CDATA[Recently, I encountered an issue while trying to validate an optional field for which I defined multiple validation rules. It&#8217;s one of those issues I call a bug whereas for the core developers it is a feature&#8230; Let&#8217;s say we have an optional &#8220;nickname&#8221; field. Its value must either be empty or an alphanumeric string [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I encountered an issue while trying to validate an optional field for which I defined multiple validation rules. It&#8217;s one of those issues I call a bug whereas for the core developers it is a feature&#8230;</p>
<p>Let&#8217;s say we have an optional &#8220;nickname&#8221; field. Its value must either be empty or an alphanumeric string with a length between three and ten characters. We start with defining the validation rules:</p>
<pre>
public $validate = array('nickname' =&gt; array('length' =&gt; array('rule' =&gt; array('between', 3, 10)),
		                             'alpha' =&gt; array('rule' =&gt; array('alphaNumeric'))));
</pre>
<p>Those rules work fine. The only &#8220;problem&#8221; is that they reject an empty string as invalid. To allow an empty string we have to set the option &#8220;allowEmpty&#8221; to true. So the $validate array is now:</p>
<pre>
public $validate = array('nickname' =&gt; array('length' =&gt; array('rule' =&gt; array('between', 3, 10)),
		                             'alpha' =&gt; array('rule' =&gt; array('alphaNumeric')),
				             'allowEmpty' =&gt; true));
</pre>
<p>It looks correct, but as you might guess, it doesn&#8217;t work. An empty string still doesn&#8217;t pass the validation. </p>
<p>The problem is that &#8220;allowEmpty&#8221; has to be set on the first rule and not as a setting for the field. And so we have to change the $validate array to:</p>
<pre>
public $validate = array('nickname' =&gt; array('length' =&gt; array('rule' =&gt; array('between', 3, 10), 'allowEmpty' =&gt; true),
		                             'alpha' =&gt; array('rule' =&gt; array('alphaNumeric'))));
</pre>
<p>With this solution, an empty string is accepted as a valid value. It&#8217;s not really logical, but it works ;-)</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/05/24/validation-of-optional-fields-with-multiple-validation-rules/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Three new validation rules</title>
		<link>http://cakebaker.42dh.com/2008/05/21/three-new-validation-rules/</link>
		<comments>http://cakebaker.42dh.com/2008/05/21/three-new-validation-rules/#comments</comments>
		<pubDate>Wed, 21 May 2008 17:32:18 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[deprecated]]></category>
		<category><![CDATA[feature]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[validation]]></category>
		<category><![CDATA[view]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=605</guid>
		<description><![CDATA[Recently, three new validation methods have been added to the core validation class and hence you can use three more validation rules in your models: boolean, inList, and time. boolean is self-explanatory: it validates whether a field contains a boolean value (i.e. 0, 1, &#8220;0&#8243;, &#8220;1&#8243;, false, or true). Example: var $validate = array('is_enabled' =&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, three new validation methods have been added to the core validation class and hence you can use three more validation rules in your models: boolean, inList, and time. </p>
<p><strong>boolean</strong> is self-explanatory: it validates whether a field contains a boolean value (i.e. 0, 1, &#8220;0&#8243;, &#8220;1&#8243;, false, or true). Example:</p>
<pre>
var $validate = array('is_enabled' =&gt; array('rule' =&gt; array('boolean')));
</pre>
<p><strong>inList</strong> ensures that the respective field only contains a value from the defined array. It is case-sensitive, i.e. if you use the rule from the example below, then the value &#8220;Red&#8221; would be invalid.</p>
<pre>
var $validate = array('color' =&gt; array('rule' =&gt; array('inList', array('red', 'green', 'blue'))));
</pre>
<p><strong>time</strong> determines whether a field contains a valid time value. It supports both the 24 hour format (e.g. 08:10:10) and the 12 hour format (e.g. 8:10:10am). The minutes and seconds are optional in both cases.</p>
<pre>
var $validate = array('starttime' =&gt; array('rule' =&gt; array('time')));
</pre>
<p>Another recent change affected View::renderElement(): it has been deprecated in favor of View::element():</p>
<pre>
$this-&gt;renderElement('my_element', array('param1' =&gt; 'a value'));

becomes

$this-&gt;element('my_element', array('param1' =&gt; 'a value'));
</pre>
<p>I don&#8217;t know why View::renderElement() was deprecated and not View::element(), as I think the method name &#8220;renderElement&#8221; is more expressive than &#8220;element&#8221;.</p>
<p>Anyway, happy baking :)</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/05/21/three-new-validation-rules/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>New core behavior: Containable</title>
		<link>http://cakebaker.42dh.com/2008/05/18/new-core-behavior-containable/</link>
		<comments>http://cakebaker.42dh.com/2008/05/18/new-core-behavior-containable/#comments</comments>
		<pubDate>Sun, 18 May 2008 16:28:25 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[behavior]]></category>
		<category><![CDATA[cakephp]]></category>
		<category><![CDATA[feature]]></category>
		<category><![CDATA[model]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=604</guid>
		<description><![CDATA[With changeset 6918 a new behavior has been introduced to CakePHP: Containable. It&#8217;s a mix of the original Containable behavior by Felix Geisendörfer (aka the_undefined) and the Bindable behavior by Mariano Iglesias. To use the new behavior, you either have to add it to the $actsAs property of your model: class Post extends AppModel { [...]]]></description>
			<content:encoded><![CDATA[<p>With <a href="https://trac.cakephp.org/changeset/6918">changeset 6918</a> a new behavior has been introduced to CakePHP: Containable. It&#8217;s a mix of the original Containable behavior by <a href="http://debuggable.com">Felix Geisendörfer (aka the_undefined)</a> and the Bindable behavior by <a href="http://cricava.com/blogs/mariano.php">Mariano Iglesias</a>.</p>
<p>To use the new behavior, you either have to add it to the $actsAs property of your model:</p>
<pre>
class Post extends AppModel {
    var $actsAs = array('Containable');
}
</pre>
<p>or you can attach the behavior on the fly with:</p>
<pre>
$this-&gt;Post-&gt;Behaviors-&gt;attach('Containable');
</pre>
<p>Ok, now let&#8217;s have a look at some examples. For the examples I will use the three models Post, Comment, and Tag, with the associations: Post hasMany Comments, Post hasAndBelongsToMany Tags.</p>
<p>If we perform a simple find all statement, then we get back all posts plus all associated records, something like:</p>
<pre>
debug($this-&gt;Post-&gt;find('all'));

[0] =&gt; Array
        (
            [Post] =&gt; Array
                (
                    [id] =&gt; 1
                    [title] =&gt; First article
                    [content] =&gt; aaa
                    [created] =&gt; 2008-05-18 00:00:00
                )
            [Comment] =&gt; Array
                (
                    [0] =&gt; Array
                        (
                            [id] =&gt; 1
                            [post_id] =&gt; 1
                            [author] =&gt; Daniel
                            [email] =&gt; dan@example.com
                            [website] =&gt; http://example.com
                            [comment] =&gt; First comment
                            [created] =&gt; 2008-05-18 00:00:00
                        )
                    [1] =&gt; Array
                        (
                            [id] =&gt; 2
                            [post_id] =&gt; 1
                            [author] =&gt; Sam
                            [email] =&gt; sam@example.net
                            [website] =&gt; http://example.net
                            [comment] =&gt; Second comment
                            [created] =&gt; 2008-05-18 00:00:00
                        )
                )
            [Tag] =&gt; Array
                (
                    [0] =&gt; Array
                        (
                            [id] =&gt; 1
                            [name] =&gt; A
                        )
                    [1] =&gt; Array
                        (
                            [id] =&gt; 2
                            [name] =&gt; B
                        )
                )
        )
</pre>
<p>But often you don&#8217;t want to get all those data, and that&#8217;s when the Containable behavior comes to the rescue. </p>
<p>To get only the posts, you can do the following:</p>
<pre>
$this-&gt;Post-&gt;contain();
debug($this-&gt;Post-&gt;find('all'));

or

debug($this-&gt;Post-&gt;find('all', array('contain' =&gt; false)));

or without the Containable behavior

$this-&gt;Post-&gt;recursive = -1;
debug($this-&gt;Post-&gt;find('all'));
</pre>
<p>With the contain() method resp. the &#8220;contain&#8221; option we specify from which of the associated models we want to get data. If we want to get all posts plus the associated tags (without the comments), we would do it in the following way:</p>
<pre>
$this-&gt;Post-&gt;contain('Tag'); // we could also use an array
debug($this-&gt;Post-&gt;find('all'));

or

debug($this-&gt;Post-&gt;find('all', array('contain' =&gt; 'Tag'))); // we could also use an array

or without the Containable behavior

$this-&gt;Post-&gt;unbindModel(array('hasMany' =&gt; array('Comment')));
debug($this-&gt;Post-&gt;find('all'));
</pre>
<p>As you can see, the code using the Containable behavior is much cleaner than the code without it.</p>
<p>But that&#8217;s not all the Containable behavior can do for you. You can also filter the data of the associated models. If you are interested in the posts and the names of the comment authors, you could write:</p>
<pre>
$this-&gt;Post-&gt;contain('Comment.author');
debug($this-&gt;Post-&gt;find('all'));

or

debug($this-&gt;Post-&gt;find('all', array('contain' =&gt; 'Comment.author')));

[0] =&gt; Array
        (
            [Post] =&gt; Array
                (
                    [id] =&gt; 1
                    [title] =&gt; First article
                    [content] =&gt; aaa
                    [created] =&gt; 2008-05-18 00:00:00
                )
            [Comment] =&gt; Array
                (
                    [0] =&gt; Array
                        (
                            [author] =&gt; Daniel
                            [post_id] =&gt; 1
                        )
                    [1] =&gt; Array
                        (
                            [author] =&gt; Sam
                            [post_id] =&gt; 1
                        )
                )
        )
</pre>
<p>As you can see, the comment arrays only contain the author plus the post_id (which is needed by Cake to map the results).</p>
<p>You can also filter the (comment) data by using a condition:</p>
<pre>
$this-&gt;Post-&gt;contain('Comment.author = "Daniel"');
debug($this-&gt;Post-&gt;find('all'));

or 

debug($this-&gt;Post-&gt;find('all', array('contain' =&gt; 'Comment.author = "Daniel"')));

[0] =&gt; Array
        (
            [Post] =&gt; Array
                (
                    [id] =&gt; 1
                    [title] =&gt; First article
                    [content] =&gt; aaa
                    [created] =&gt; 2008-05-18 00:00:00
                )
            [Comment] =&gt; Array
                (
                    [0] =&gt; Array
                        (
                            [id] =&gt; 1
                            [post_id] =&gt; 1
                            [author] =&gt; Daniel
                            [email] =&gt; dan@example.com
                            [website] =&gt; http://example.com
                            [comment] =&gt; First comment
                            [created] =&gt; 2008-05-18 00:00:00
                        )
                )
        )
</pre>
<p>As you can see from these examples, the Containable behavior is very powerful, and I recommend to have a look at the tests.</p>
<p>Anyway, it&#8217;s very cool to have this behavior in the core :)</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/05/18/new-core-behavior-containable/feed/</wfw:commentRss>
		<slash:comments>39</slash:comments>
		</item>
		<item>
		<title>A missing concept: model &#8220;components&#8221;</title>
		<link>http://cakebaker.42dh.com/2008/05/15/a-missing-concept-model-components/</link>
		<comments>http://cakebaker.42dh.com/2008/05/15/a-missing-concept-model-components/#comments</comments>
		<pubDate>Thu, 15 May 2008 08:43:55 +0000</pubDate>
		<dc:creator>cakebaker</dc:creator>
				<category><![CDATA[cakephp]]></category>
		<category><![CDATA[component]]></category>
		<category><![CDATA[ideas]]></category>
		<category><![CDATA[model]]></category>

		<guid isPermaLink="false">http://cakebaker.42dh.com/?p=603</guid>
		<description><![CDATA[The fatter your models become, the more obvious it is (at least for me) that something is missing. Let&#8217;s say we have a bunch of models. Two of those models use internally the same functionality. To avoid code duplication, you want to share this functionality between the two models. But how could you accomplish that? [...]]]></description>
			<content:encoded><![CDATA[<p>The fatter your models become, the more obvious it is (at least for me) that something is missing. Let&#8217;s say we have a bunch of models. Two of those models use internally the same functionality. To avoid code duplication, you want to share this functionality between the two models. But how could you accomplish that? </p>
<p>One idea is to move the functionality to the AppModel. That works, but it is a dirty solution. The AppModel should contain generic functionality relevant for all models, and not functionality specific to only two models. </p>
<p>Another idea is to move the functionality into a class in the vendors folder and to load it with App::import(). That works fine, but if you compare this solution with elements and helpers for reusing view functionality, and with components for reusing controller functionality, it is a bit strange there is no &#8220;native&#8221; solution for models (sure, there are behaviors, but they are not designed for the kind of code reuse I described above).</p>
<p>Hence I think it would be useful to have model &#8220;components&#8221;, which could be realized in the same way as controller components are realized. For example:</p>
<pre>
class Example extends AppModel {
    public $components = array('X');

    public function doSomething() {
        ...
        $this-&gt;X-&gt;doSomethingElse(); // using model component
        ...
    }
}
</pre>
<p>In the longer term it would even make sense to have a unified &#8220;components&#8221; concept to replace the current concepts of components and helpers. But well, we will see what the future brings ;-)</p>
]]></content:encoded>
			<wfw:commentRss>http://cakebaker.42dh.com/2008/05/15/a-missing-concept-model-components/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
	</channel>
</rss>

