A Weblog written, styled and hacked by Joel Moss
I discovered the joys of NamedScope for Ruby on Rails quite a while ago now, and have always been an admirer. Its makes performing finds on models very elegant and convenient, by automagically creating model methods based on your pased scope params. Just like this:
Then a few months ago I read this blog post and discovered that someone had created similar functionality for CakePHP, in the form of a model behavior. Although it’s not quite as powerful as it’s Rails cousin, it does let you define named scopes for any model quite easily. However, I wasn’t crazy about a few things.
Named Scopes are defined like this:
The above format means we can only pass find conditions to a named scope, and cannot pass any other params, such as ORDER and FIELDS.
Then a named scope is then called like this:
I have to pass enough params to a find call as it is, so I don’t want anymore.
What I want to do is this:
and this
I can even do this:
Much improved I think, and so much more powerful. So I’ve only gone and coded the damn thing! You can find my version of Named Scope for Cake on Github at http://github.com/joelmoss/cakephp-namedscope.
And you know what? Thanks to the power of CakePHP, the actual code is seven lines shorter than the aforementioned version.
My name is Joel Moss, a web developer and all round nice guy, living in Manchester, England. I am currently working full time for ShermansTravel.com, but I fill whatever spare time I have with lots of good and wholesome "stuff"! Like developing my own ideas; such as Tooum, contributing to the excellent CakePHP framework, and doing more work for ShermansTravel.
So this is my blog - my soap box! Here I attempt to share my likes, my dislikes, and my opinions. As well as providing some occasional respite from the daily crap we all endure. Enjoy ;)
Hey, if you want to reach me, i'm available via email:joel[at]developwithstyle[dot]com, and AIM:joelkmoss.
Luke
November 20th, 2008 at 3:27 pm
put it on the Bakery!
Neil Crookes
November 20th, 2008 at 4:25 pm
Nice one. That’ll be finding it’s way into my apps.
kuba
November 21st, 2008 at 12:51 am
Your solution looks cleaner, that’s true. What about using your bahavior with paginate() ?
Joel
November 21st, 2008 at 1:46 am
@kuba: not tested with paginate yet, but will soon. Feel free to fork away!
Signets remarquables du 21/11/2008 au 24/11/2008 | Cherry on the...
November 24th, 2008 at 1:02 pm
[...] NamedScope for CakePHP [...]
gwoo
December 9th, 2008 at 3:01 pm
Once you start adding ‘fields’ and ‘order’ you pass the idea of the scope and might be better off using _findMethods.
Joel
December 10th, 2008 at 9:14 am
Take a look at the code gwo, and you will see that NamedScope already uses _findMethods. Oh the power of Cake!
evilbloodydemon
December 10th, 2008 at 6:06 pm
Thanks, this behavior is very useful, but i made some changes (see diff). I think it makes more sense to override scope conditions, order, etc in find call. And now it supports condition merge.
diff -r bfcb4b6ec209 -r f2493fdbfa3b www/app/models/behaviors/named_scope.php
— a/www/app/models/behaviors/named_scope.php Wed Dec 10 19:41:53 2008 +0300
+++ b/www/app/models/behaviors/named_scope.php Wed Dec 10 20:30:30 2008 +0300
@@ -80,7 +80,7 @@
{
if ($state == ‘before’) {
preg_match(’/^_find(\w+)/’, $method, $matches);
- $params = array_merge($params, $this->_settings[$model->alias][$matches[1]]);
+ $params = Set::merge($this->_settings[$model->alias][$matches[1]], $params);
return $params;
} elseif ($state == ‘after’) {
return $results;