I'm aware that Cake HABTM associations are tricky at the best of times, but I seem to be making life even harder for myself...
If I want to return a random Item from the db, I can do it as follows in the Item model:
$random = $this->find('first', array(
'order' => 'rand()'
));
and if I want to find all the Items that are in a certain Category (where Item has a HABTM relationship to Categories), I know I can get a result set through $this->Categories->find.
My question is: how can I combine the two, so I can return a random Item that belongs to a specified Category? Is there any easy way? (If not, I'll gladly take any suggestions for a laborious way, as long as it works ;)
ETA: I can get some of the way with Containable, maybe: say I add the line
'contain' => array('Categories'=>array('conditions'=>array('Categories.id'=>1))),
then the Item results that I don't want come back with an empty Categories array, to distinguish them from "good" items. But really I don't want said Item results to be returned at all...
ETA(2): I can get a workaround going by unsetting my results in the afterFind if the Categories array is empty (thanks to http://nuts-and-bolts-of-cakephp.com/2008/08/06/filtering-results-returned-by-containable-behavior/ for the tip), and then having my random find function not give up until it gets a result:
while (!is_array($item)) {
$item = $this->random($cat);
}
but ugh, could this be any clunkier? Anyway, time for me to stop editing my question, and to go away and sleep on it instead!
Try this:
<?php
$this->Item->bindModel(array('hasOne' => array('ItemsCategory')));
$random = $this->Item->find('all', array(
'order' => 'rand()',
'conditions' => array('ItemsCategory.category_id' => '1')
));
?>