Containable 2.0 BETA
Posted by Felix Geisendörfer, on Jun 14, 2007 - in PHP & CakePHP » DataSources, Models & Behaviors
Deprecated post
The authors of this post have marked it as deprecated. This means the information displayed is most likely outdated, inaccurate, boring or a combination of all three.
Policy: We never delete deprecated posts, but they are not listed in our categories or show up in the search anymore.
Comments: You can continue to leave comments on this post, but please consult Google or our search first if you want to get an answer ; ).
PLEASE READ: CakePHP now includes a version of this behavior natively. Please use that version instead of the one downloadable here as it contains many bug fixes and additional features.
Hi folks,
sorry I've taken so long to get a new version of my Containable Behavior released, but believe me I've not been slacking this time. Rather I noticed that my initial plan of refactoring, adding a couple features and unit testing the behavior (especially the later) turned out to be much more ambitious than I thought it would be. In fact I'm releasing the new version as a BETA right now since I'm still not 100% satisfied with the result and not all features have made it in yet, but I felt the need for iterating. However, the new version should be a big step up from this initial one and I hopefully bug free.
Where is the code?
Note: I just tried running the unit test in PHP4 and it's failing. Will need to investigate what's going on there. So for now I only recommend usage for people running PHP5 would love PHP4 users to test the behavior and let me know if it works for them or not.
Update: My initial investigation has shown that it might be impossible to write a useful unit test for this behavior in PHP4. Apparently PHP4 chokes on verifying that two self-containing class instances are identical:
-
debug($this->User === $this->User->Post->User);
Generates the following error in PHP4: "Fatal error: Nesting level too deep - recursive dependency?".
So what does this mean for PHP4 users? Well give the behavior a try and see if it does what it's supposed to. I think it should be working regardless of the problems above but I have no rational way to verify it at this point.
What has improved?
- Performance be better then in version 1.0
- A new function containments() has been added that flattens the assoc tree and makes debugging easier.
- Support for dynamic field containments
- Support for different field containments for the main model and later assoc references to it
How to use the new Goodies?
Containable 2.0 is 100% syntax compatible to version 1.0. This means you can keep all your existing code based on it without having to change anything. However, additionally you are now able to specify what fields to include for what associations dynamically:
The most verbose way to do it looks like this. The following code will only fetch only the Group.id's associated with the current User + the User data itself. Group.name and other fields will not be returned:
Now of course you can get a little more succinct then the above:
Or even better:
Still not the shortest:
-
$this->User->contain('Group.fields.id');
And yup, you've guessed it, this is for the laziest amongst us:
-
$this->User->contain('Group.id');
Which syntax is the best? Well I usually like it short, but I know you can easily loose the overview between included models and fields in a big containment array so I've decided to leave you with the freedom to specify a 'fields' array for your field containments where you see fit.
One thing that's important to know is that you can also specify the $fields parameter to use for your main model find call with the new behavior, which you shouldn't mix up with the above:
-
$this->User->contain('group_id');
You also need to know that the Containable behavior tries to be a smart ass. So if you try to trick it with something like this:
-
$this->User->contain('id', 'Group');
Then it will notice that you forgot to include the User.group_id field which is necessary to fetch the Group association and the behavior will automatically add it for you.
What other features are missing / planned?
- Support for setting all other association fields like 'order', 'conditions', 'limit' etc. on the fly
- Configuration options for the behavior, i.e. making it behave persistently and not reset after a find call automatically
- A more elegant unit test. The current one isn't bad and was hard to do, but I hope to be able to come up with something better.
- I'm open for suggestions about other features, drop a comment!
All right I hope you enjoy this new version of the behavior and can help me with testing it on the battlefield a little more then I was able to do so far and I'm interested in hearing your feedback.
-- Felix Geisendörfer aka the_undefined