Thursday, November 25, 2010

Changing join to bindModel

I am trying to find posts within a category that are associated with a category. Right now, I have this:

$this->set('posts', $this->Category->Post->find('all', array('conditions' => array('Category.uri' => $uri))));  
But this doesn't seem to work. An error is showing this:

Warning (512): SQL Error: 1054: Unknown column 'Category.uri' in 'where clause' [CORE/cake/libs/model/datasources/dbo_source.php, line 684]  ..<snipped>...  Query: SELECT `Post`.`id`, `Post`.`title`, `Post`.`uri`, `Post`.`body`, `Post`.`created`, `Post`.`modified` FROM `posts` AS `Post` WHERE `Category`.`uri` = 'holidays'. 
My Models
 // Category Model class Category extends AppModel {     var $name = 'Category';     var $hasAndBelongsToMany = array(         'Post' => array(             'className' => 'Post'         )     ); }  // Post Model class Post extends AppModel {     var $name = 'Post';     var $hasAndBelongsToMany = array(         'Category' => array(             'className' => 'Category'         )     ); }  
This doesn't seem to work. I used join as I would have if this was just SQL via CakePHP join

$options['joins'] = array(     array('table' => 'categories_posts',         'alias' => 'CategoriesPosts',         'type' => 'LEFT',         'conditions' => array(             'Category.id = CategoriesPosts.category_id'         )     ),     array('table' => 'posts',         'alias' => 'Post',         'type' => 'LEFT',         'conditions' => array(             'CategoriesPosts.post_id = Post.id',         )     ) ); $options['conditions'] = array(     'Category.uri' => $uri ); $options['fields'] = array(     'DISTINCT(Category.uri), Post.*, Category.*' ); $this->set('posts', $this->Category->find('all', $options));  
It worked but somehow a comment from stackoverflow was this:

There's nothing spectacularly wrong with solving your problem this way.  The only caution I'd give is that you're breaking Cake's ORM abstraction  some. You can achieve this same effect with Model::bindModel that don't require your Models know all about your how your Datasources work.  
My question is this. How do I used bindModel to retrieve what I need without the join?

No comments: