I'd also call the function genre() in case I ever wanted to add a broader similar() functionality.
On Sun, Apr 12, 2009 at 3:25 PM, brian <[email protected]> wrote: > There's no need to search on Genre as you have the foreign key already. > > function similar($genre_id) > { > return $this->find( > 'all', > array( > 'fields' => array( > 'Book.id', > 'Book.title', > 'Book.slug' > ), > 'conditions' => array( > 'Book.genre_id' => $genre_id > ), > 'contain' => array( > 'Author' => array( > 'fields' => array( > 'Author.id', > 'Author.slug', > 'Author.lastname' > ) > ), > 'Language' => array( > 'fields' => array( > 'Language.id', > 'Language.name' > ) > ) > ) > ) > ); > } > > On Sun, Apr 12, 2009 at 8:25 AM, Mike Cook <[email protected]> wrote: >> >> Okay, so after more searching around I found a post by pkclarke who >> makes use of a search on the join table, and then uses a find() with >> those results. >> >> I still have the feeling this is not the best way it should be done, >> but I think this approach will allow me to move forward....and no >> requestAction. >> >> // in the book.php model >> function similar($id) { >> >> $books_genres = $this->BooksGenre->find('list', >> array( >> 'conditions' => array('genre_id' => $id), >> 'fields' => array('book_id'), >> 'limit' => 5, >> 'order' => 'RAND()', >> ) >> ); >> >> $similarBooks = array(); >> foreach ($books_genres as $value) { >> $book = $this->find('first', >> array( >> 'conditions' => array('Book.id' => $value), >> 'contain' => array( >> 'Author' => array('fields' => array('id', 'slug', >> 'lastname')), >> 'Language' => array('fields' => array('id', 'name')), >> ), >> 'fields' => array('id', 'slug', 'title') >> ) >> ); >> $similarBooks[] = $book; >> } >> return $similarBooks; >> } >> >> // books_controller.php >> // $genre_id is an array() of Genre ID's associated with the >> current book being viewed >> $similar = $this->Book->similar($genre_id); >> >> >> I was also pleasantly surprised that I could pass the $id array to >> 'conditions' and it would use it as an 'OR' :) >> >> Thanks for your help Joe, your comments really helped to point on the >> right path. >> >> Mike >> >> On Apr 11, 8:45 pm, Mike Cook <[email protected]> wrote: >>> Hi Joe, >>> >>> During my experimentations I did come up with something similar, but >>> one of the problems is how to set the conditions to work on the Genre >>> ID. >>> >>> So, I have a book that has two genre, "Mystery" (id=5) and "Short >>> Story" (id=20) and if I only try to search with say, "Mystery"; >>> >>> $id = 5; >>> $this->Genre->Book->similar($id); >>> >>> The problem is that I don't know how to set the 'conditions' in the >>> find() so that it only brings up Books that have a Genre ID of 5. >>> >>> I can't get 'conditions to work and I thought maybe I could use; >>> >>> 'contain => array('Genre.id' => $id), >>> >>> but I get the error; Model "Genre" is not associated with model "5" -- >>> obviously I don't know what I'm doing. :-| >>> >>> How would I go about setting the conditions to grab books that only >>> have that Genre ID? >>> >>> Mike >>> >>> On Apr 11, 7:31 pm, Joe Critchley <[email protected]> wrote: >>> >>> > You've currently got your similar() function in your >>> > genres_controller, whereas the primary model for the query is the Book >>> > model (as it's finding related *books*, not genres). >>> >>> > I believe the following would be a more scalable approach. >>> >>> > Place your similar() function into your Book model. (So it would >>> > be ....... $similarBooks = $this->find('all')............ and just >>> > return your results). >>> >>> > Then call this model's function from wherever you need it, whether it >>> > be the genres_controller: >>> >>> > $this->Genre->Book->similar($id); >>> >>> > ... or your books_controller.... >>> >>> > $this->Book->similar($id); >>> >>> > .... or even from a completely unrelated model (use sparingly).... >>> >>> > $Book = ClassRegistry::init('Book'); >>> > $similar = $Book->similar(); >>> >>> > It's possible that I'm missing the actual issue, but two important >>> > points: 1) never use requestAction (as you probably know), and 2) >>> > there should never be any variables in your views that aren't >>> > available in your controllers, because there shouldn't be any new >>> > variables assigned. If this is ever required, you're likely in need of >>> > a Helper class. And yes, it would be worth looking at creating >>> > elements for anything like "Similar books", or "5 Related Authors". >>> > You can pass variables into elements. >>> >>> > I hope this helps. >>> >>> > On Apr 11, 5:00 pm, Mike Cook <[email protected]> wrote: >>> >>> > > In my books view.ctp, I want to have a list of 5 books that are >>> > > related via the genres data, which has a HABTM relationship. Although >>> > > I can do this by placing a function similar() in the >>> > > genres_controller, I have to call it from the view with requestAction. >>> >>> > > // genres_controller.php >>> > > function similar($id = null) { >>> > > $similarbooks = $this->Genre->Book->find('all', array( >>> > > 'contain' => array( >>> > > 'Author' => array('fields' => array('id', 'slug')), >>> > > ), >>> > > 'fields' => array('id', 'slug', 'title'), >>> > > 'limit' => 5, >>> > > 'order' => 'RAND()', >>> > > )); >>> > > $this->set(compact('similarbooks')); >>> > > } >>> >>> > > // Book view.ctp >>> > > $results = $this->requestAction('/genres/similar/' . $id); >>> >>> > > Of course I don't want to really use requestAction (the only place so >>> > > far I have used it!) but I would also like to be able to bring up 5 >>> > > random books from ALL the genres the book is assigned to - at the >>> > > moment I am just searching on one genre id. >>> >>> > > I also know that this approach is not very good if I wish to include 5 >>> > > books which are related to say, both Genre and Author. >>> >>> > > At some point down the line I would also like to include a "5 Related >>> > > Authors" list, so I guess I need a more modular approach (would >>> > > elements be it?) - the problem is that I am completely stumped, even >>> > > after a week looking at this! >>> >>> > > The solution I currently have is better than nothing, but I would be >>> > > very grateful if anyone has an idea on how I could achieve a proper >>> > > solution. >>> >>> > > Many thanks, Mike. >> >> >> > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "CakePHP" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/cake-php?hl=en -~----------~----~----~----~------~----~------~--~---
