Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cake HABTM Query, Order By Rand()

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!

like image 745
thesunneversets Avatar asked Nov 08 '10 07:11

thesunneversets


1 Answers

Try this:

<?php
$this->Item->bindModel(array('hasOne' => array('ItemsCategory')));
$random = $this->Item->find('all', array(
  'order' => 'rand()',
  'conditions' => array('ItemsCategory.category_id' => '1')
  ));
?>
like image 73
pawelmysior Avatar answered Sep 30 '22 00:09

pawelmysior