CakePHP:几个连接,belongsTo和hasMany关系在两个查询中完成
我需要一些Cake
PHP 2.2.3的帮助.
是)我有的 我现在有以下设置: 邮寄hasMany附件 它工作正常,页面生成2个查询: SELECT *,`Post`.`id` FROM `posts` AS `Post` WHERE 1 = 1 ORDER BY `Post`.`created` DESC SELECT `Attachment`.`id`,`Attachment`.`post_id`,`Attachment`.`created` FROM `attachments` AS `Attachment` WHERE `Attachment`.`post_id` IN (1,2,3,...,n) 我想要的是 我想将关系扩展如下: 邮政有很多附件;每个附件属于所有类型 我不太热衷于让CakePHP遵循它. SELECT *,`Attachment`.`created`,`Type`.`title`,`Type`.`icon` FROM `attachments` AS `Attachment` LEFT JOIN `types` AS `Type` ON (`Attachment`.`type_id`=`Type`.`id`) WHERE `Attachment`.`post_id` IN (1,n) 请注意添加了LEFT JOIN类型. 所以我在第二个查询中得到了相应的类型数据.我知道我可以循环获取数据或使用 – > query()调用,但我希望它尽可能有效和灵活. 问题 我尝试了Containable,Model Unbinding trick(and this one)但没有成功.我尝试了不同的选项组合,我相信我甚至删除了连接.这就是我的PostsController现在的样子. class PostsController extends AppController { public function index() { $this->Post->unbindModel(array('hasMany' => array('Attachment'))); $this->Post->Attachment->unbindModel(array('belongsTo' => array('Type'))); $this->Post->bindModel(array( 'hasMany' => array( 'Attachment' => array( 'className' => 'Attachment',// when uncommented,throws the "Unknown column Post.id" SQLSTATE error // 'conditions' => array('Post.id' => 'Attachment.post_id'),'foreignKey' => false,),)); $this->Post->Attachment->bindModel(array( 'belongsTo' => array( 'Filetype' => array( 'className' => 'Filetype',// 'conditions' => array('Type.id' => 'Attachment.type_id'),)); $all = $this->Post->find('all',array( 'joins' => array( array( 'table' => 'users','prefix' => '','alias' => 'User','type' => 'INNER','conditions' => array( 'User.id = Post.user_id',) ),'contain' => array('Attachment','Type'),'conditions' => array(),'fields' => array('*'),'order' => 'Post.created ASC' )); var_dump($all);exit; } } 但它只是在循环中每次迭代运行一个额外的查询并获取所有附件: SELECT `Attachment`.`id`,... FROM `attachments` AS `Attachment` WHERE 1 = 1 当我取消注释这个关联的条件时,它会抛出SQLSTATE“Column Post.id not found error” – 我想因为这里没有Post表加入. 我需要帮助设置它. 请帮忙!谢谢 UPDATE 我按如下方式更改了控制器.请注意,没有bindModel / unbindModel代码,关系是在models类中设置的(在这种情况下是正确的吗?). class PostsController extends AppController { public function index() { $options = array( 'contain' => array( 'Post','Type' ),'order' => 'Post.created DESC','conditions' => array( // 'Post.title LIKE' => 'my post' ) ); // The following throws "Fatal error: Call to a member function find() on a non-object" // $posts = $this->Attachment->find('all',$options); // So I had to use $this->Post->Attachment instead of $this->Attachment $posts = $this->Post->Attachment->find('all',$options); $this->set(compact('posts')); } } 这是附件模型: class Attachment extends AppModel { public $belongsTo = array( 'Type' => array( 'className' => 'Type','foreignKey' => 'type_id','Post' => array( 'className' => 'Post','foreignKey' => 'post_id',); } 上面的代码运行此查询: SELECT `Attachment`.`id`,`Attachment`.`type_id`,`Type`.`id`,`Post`.`id`,`Post`.`text`,`Post`.`created` FROM `attachments` AS `Attachment` LEFT JOIN `types` AS `Type` ON (`Attachment`.`type_id` = `Type`.`id`) LEFT JOIN `posts` AS `Post` ON (`Attachment`.`post_id` = `Post`.`id`) WHERE 1 = 1 ORDER BY `Post`.`created` ASC 一切都是关于这里的附件.我的意思是帖子已加入附件,因此如果帖子没有附件,则不会返回.这可能是因为调用是Attachment-> find()所以它来自附件的观点.我猜它应该是: // ... FROM `posts` AS `Post` LEFT JOIN `attachments` AS `Attachment` ON (`Attachment`.`post_id` = `Post`.`id`) LEFT JOIN `types` AS `Type` ON (`Attachment`.`type_id` = `Type`.`id`) // ... 但它不会起作用,是吗?您会看到有帖子,附件和类型,但它们确实具有不同的关系类型.最初,我发布了CakePHP运行的两个单独的查询 – 必须有这样的理由. UPDATE2 我仍然相信在初始设置中将第二个查询更改为附件模型(请参阅“我想要的内容”部分).所以我将获得附件类型以及附件本身.我的意思是在那种情况下LEFT JOINING类型表到附件不会打破任何数据库关系逻辑,是吗? 解决方法
每当Cake看到hasMany关系时,它都会自动创建多个查询来提取数据.在构造这些查询时,它会查找可以LEFT连接到它的关系(hasOne和belongsTo).
由于Cake无法为您执行此操作,因此您需要自己合并它们. public function index() { $posts = $this->Post->find('all'); // get all attachments for all found posts $attachments = $this->Post->Attachment->find('all',array( 'contain' => array('Type'),'conditions' => array('Post.id' => Set::extract('/Post/id',$posts) )); // now join them to the posts array foreach ($posts as $key => $data) { $postId = $data['Post']['id']; // append any data related to this post to the post's array $posts[$key] += Set::extract("/Attachment[post_id=$postId]/..",$attachments); } $this->set(compact('posts')); } 这不是最有效的方法,因为你将多次遍历$attachments数组,但我相信你明白了. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |