CakePHP 2.x包含深层关联的行为条件 [英] CakePHP 2.x containable behavior conditions on deep associations
问题描述
我有这样的模型关系:
项目
hasMany SubProject
hasMany Item
Project
hasMany SubProject
hasMany Item
我想设置一个 c $ c>数组,以便我可以找到属于特定
Project
的所有 Item
结果。所以,在我的 ItemsController
我有:
I want to set up a containable
array so that I can find all of the Item
s which belong to a particular Project
, and paginate the results. So, in my ItemsController
I have:
public $paginate = array(
'Item' => array(
'limit' => 10,
'order' => array('
'Item.create_time' => 'desc'
),
'contain' => array(
'SubProject' => array(
'Project'
)
)
)
);
显然,我需要放置一个条件,例如SubProject.project_id = $ pid
,但我没有尝试产生正确的结果。我可以管理的最好的结果是这样的:
Somewhere, obviously, I need to place a condition like "SubProject.project_id = $pid"
, but nothing I've tried yields the correct results. The best I can manage is results that look like this:
Array
(
[0] => Array
(
[Item] => Array
(
[id] => 13
[file_name] => foo.tar.gz
.... other keys ...
[create_time] => 2013-01-23 14:59:49
[subProject_id] => 4
)
[SubProject] => Array
(
[id] => 4
[name] => foo
[project_id] => 2
..... other keys ....
[Project] => Array
(
)
)
)
[1] => Array
.....
编辑:完全正确地忽略不匹配的项目记录;我想跳过任何项目记录,匹配项目记录。
Edit: It is quite correctly omitting the Project record that doesn't match; I want to skip any Item records with out a matching Project record.
它已经过我的想法,手动指定我的联接
似乎这应该是显而易见的,但唉,解决方案逃脱了我。
It seems like this should be obvious, but alas, the solution escapes me.
推荐答案
我最终解决了这个问题,所以我想我会解释我做了什么,希望它可以帮助别人。
I did eventually solve this problem, so I thought I'd explain what I did in the hope it might help someone else.
阅读本篇博文Mark Story (这是从1.2的日子,但仍然相关)我决定要做的事情是在我的项目模型中创建一个自定义查找类型,直接绑定项目模型。
After reading this blog post by Mark Story (which is from the days of 1.2 but still relevant) I decided that the thing to do was create a custom find type in my Item model that binds the Project model directly. This gives a first-level association that Containable can filter correctly.
所以,在Items模型中,我有类似下面的内容(见关于自定义查找类型的文档)。
So, in the Items model, I have something like the following (see the documentation on custom find types).
public $findMethods = array('byProject' => true);
public function _findByProject($state, $query, $results=array()) {
if ($state == 'before') {
$this->bindModel(array(
'hasOne' => array(
'Project' => array(
'foreignKey' => false,
'conditions' => array('Project.id = SubProject.project_id')
)
)
));
return $query;
}
return $results;
}
请注意,设置 foreignKey
to false防止CakePHP尝试自动使用不存在的数据库密钥。在ItemsController中,分页选项现在如下:
Note that setting foreignKey
to false is necessary to prevent CakePHP from trying to automatically use a non-existent database key. In the ItemsController, the pagination options now look like this:
public $paginate = array(
'Item' => array(
'findType' => 'byProject',
'limit' => 10,
'order' => array(
'Item.create_time' => 'desc'
),
'contain' => array(
'SubProject',
'Project'
),
'conditions' => array('Project.id' = $pid)
),
);
...其中 $ pid
要显示的项目的ID。视图代码中的一些细微调整,以适应稍微不同的结果数组结构,我都设置了。
...where $pid
is the id of the project to display. Some minor tweaks in the view code to accomodate the slightly different results array structure, and I was all set.
这篇关于CakePHP 2.x包含深层关联的行为条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!