articles
CakePHP 1.2 GROUP BY with HAVING COUNT(*) HABTM associations (limit the query based on associated data)
by volve on Mar.26, 2009, under articles, web
The problem: Your models look like this “Images HABTM Albums” so when you want to show 4 Albums, they come along with their Images too – great! BUT, what happens if some Albums don’t have any Images? You don’t want to show those to your users, but how do you filter them out? Well you could do it after the find() has run, in which case you may end-up with less than 4 useable Albums – bad
To workaround that you could always ask find() to give you 8 Albums in the hope that at least 50% of them will be useable, but there’s no guarantee – still bad.
The solution below takes advantage of CakePHP 1.2’s bindModel() method to manually create an INNER JOIN in place of the pre-defined HABTM association. This allows us to execute the find() with a HAVING COUNT(*) in the group option. In the example below, this causes any Albums with 0 Images to be omitted from the results as they don’t meet the HAVING criteria. What’s more, the limit of 4 correlates exactly so 8-just-incase kludge needed.
This was driving me crazy so here’s the solution for anyone else that might be stuck in the same situation. (This method is in the Albums model.)
function getAlbums($num=4) {
$contain = array( // use Containable Behavior for efficiency 'AlbumsImage',
'FilterImage',// although part of the magic and required, this seems to confuse CakePHP a little - I'll try and resolve it and update the post
'Image',
'Image'=>array('ImageSize',
'fields'=>array('Image.id','Image.title','Image.host','Image.path')),
'User'=>array('fields'=>'User.id,User.username'));
$this->bindModel(array('hasOne'=>array('AlbumsImage',
'FilterImage'=>array( // FilterImage so as to distinguish between regular Image
'className'=>'Image',
'foreignKey'=>false,
'type'=>'INNER',
'conditions'=>array(
'FilterImage.status = 0',
'FilterImage.id = AlbumsImage.image_id')
)
)
));
$albums = $this->find('all', array('contain' => $contain,
'conditions' => array('Album.status'=>'0'),
'fields' => array('Album.id','Album.user_id','Album.title'),
'order' => 'Album.created DESC',
'limit' => $num,
'group' => array('Album.id','Album.title HAVING COUNT(*) >= 1'))); // here's the clincher
return $albums;
}
media server software rant update (mini review)
by volve on Feb.06, 2006, under articles, media storage, movies, software, ui
It appears that the sorry state of UIs in media server software doesn’t extend to the Mac platform. I’ve been surfing around reading a few obscure articles this week and although the software isn’t very mature, I’ve been quite impressed with several Mac projects. Namely: MediaCentral, CenterStage, iTheatre, and CoverFlow. The best part is that unlike some of the Windows appliations, these three for the Mac are free! (Try saying that ten times fast.)
Although MediaCentral is quite text-based for navigation, its presentation is definitely a lot sharper and more refined than any of the others. CenterStage is intersting and has a lot of potential, but better be careful not to ‘over utilize’ available space. It’s definitely the most mature of the projects. My main gripe is that if I’m browsing a bunch of movie covers (which BackStage – the CenterStage backend component sucsessfully downloaded for me), why do I need a text title underneath them? I don’t; it simply wastes space. Also the cover browsing section seems awfully small, but as I didn’t poke too deeply, one might be able to turn off the preview area to the right (that would be handy). iTheatre is at RC1 currently and has quite a few pieces of missing functionality, but could be nice although is heavily text-based like MediaCentral. CoverFlow is purely for browsing your music but it is such a simple, obvious UI that it merits mentioning. Hopefully its ideas can be intergrated into a more encompassing media browser.
RDP over SSH
by volve on Jan.19, 2006, under articles, linux, software
I’d been having some annoyances with RDP (Remote Desktop) over SSH. The primary source of annoyance stemmed from the Win2k/XP client not allowing you to connect to your local IP regardless of port, forwarded or otherwise. Luckily, it isn’t actually clever enough to know that the 127.0.0.2 address is also tied to the loopback device (one of Microsoft’s little liberties that turns out to actually be handy – who knew?!). So, here’s a solution that’ll save you time struggling and cash from buying an application such as WiSSH that is entirely unnecessary.



