如何更改';联接';用CakePHP?
我对连接的顺序有问题。类似的问题出现在另一个问题中。答案是使用可控制的行为。在我的例子中,这是不可接受的,因为我有更深的关联,containable生成了太多的查询。Containeable不会为三级关联生成联接。它为第二级表中的每个条目生成附加查询 我的问题是:如何更改';联接';用CakePHP?,php,cakephp,join,model,associations,Php,Cakephp,Join,Model,Associations,我对连接的顺序有问题。类似的问题出现在另一个问题中。答案是使用可控制的行为。在我的例子中,这是不可接受的,因为我有更深的关联,containable生成了太多的查询。Containeable不会为三级关联生成联接。它为第二级表中的每个条目生成附加查询 我的问题是: $this->LevelOne->find('all', array( 'joins' => array(array( 'table' => 'level_three',
$this->LevelOne->find('all', array(
'joins' => array(array(
'table' => 'level_three',
'alias' => 'LevelThree',
'type' => 'LEFT',
'conditions' => array(
'LevelThree.id = LevelTwo.level_three_field_id'
)
))
));
这里的问题是,cake生成多个联接,但LevelThree表的联接在LevelThree表的联接之前完成,这会在“on子句”中抛出一个SQL错误“未知列'LevelThree.LevelThree'field'id'。如果在所有LevelTwo连接之后,LevelTwo连接将位于查询的末尾,那么查询就可以了
所以,问题是如何改变连接的顺序 您是否考虑过创建HABTM模型并插入您自己的“finderQuery”来覆盖模型查询? 有时对于复杂的查询,创建自定义查询更有意义,这样cake就不必处理它了。为此,您可以在模型中创建函数,然后像调用任何其他查询一样调用它
function customJoin(){
return $this->query('CUSTOM QUERY HERE');
}
然后从控制器调用它:
$this->ModelName->customJoin();
我认为有时我们过于依赖框架提供的自动化,而忘记了我们是在控制中,可以在核心之外实现代码。我总是这样做。希望这能有所帮助。我终于想出了办法:
$this->LevelOne->unbindModel(array('belongsTo' => array('LevelTwo')));
$this->LevelOne->find('all', array(
'joins' => array(
array(
'table' => 'level_two',
'alias' => 'LevelTwo',
'type' => 'LEFT',
'conditions' => array(
'LevelTwo.id = LevelOne.level_two_field_id'
)
),
array(
'table' => 'level_three',
'alias' => 'LevelThree',
'type' => 'LEFT',
'conditions' => array(
'LevelThree.id = LevelTwo.level_three_field_id'
)
)
)
));
对于那些有类似问题但关系a-la$belongsTo的人,为了有正确的顺序,你应该正确地设置它 例如,当您有这样的代码时:
var $belongsTo = array(
'Vacancy',
'Applicant' => array(
'className' => 'Person',
),
'Recruiter' => array(
'className' => 'Person',
),
'Company' => array(
'conditions' => array('Company.id = Vacancy.company_id'),
),
);
但是在result always receive results中,空缺总是最后加入,您应该做一件简单的事情:添加那些“空缺”模型,而不是作为数组值,而是作为键=>值,与其他值一样:
var $belongsTo = array(
'Vacancy' => array(), // Just add empty array here -- all magic is here :)
'Applicant' => array(
'className' => 'Person',
),
'Recruiter' => array(
'className' => 'Person',
),
'Company' => array(
'conditions' => array('Company.id = Vacancy.company_id'),
),
);
现在所有这些都将按顺序排列:空缺、申请人、招聘人员&只有公司。与问题相关的表格之间没有HABTM关系。由于缺少文档,我并没有真正考虑
finderQuery
。但我想这应该包含一个原始查询。我说得对吗?我希望避免在我的应用程序中使用$this->query(),以保持数据抽象到位,并保持应用程序在数据库之间的可移植性。最后一种解决方案是,如果无法更改连接顺序,则解除绑定并绑定模型。cdburges的基本意思是将$this->query(…)包装在一个model方法中(因为我认为您不能使用finderQuery w/o HABTM关系)。我不认为编写自己的自定义查询有任何问题,只要它们驻留在模型中。它们将在数据库之间保持可移植性,因为它仍然包装在PDO层中。数据抽象仍然存在——您只是根据您的应用程序需求扩展它。我认为这是非常可以接受的。事实上,桌子之间有一种关系,或者你不能加入它们。您可能是正确的,因为它们可能不是HABTM,但是,finderQuery选项将覆盖自动查询,并基本上基于您提供的查询提供自定义HABTM模型。我知道这可能会引起一些争议,但可以将其视为sql视图。您正在尝试将多个表中的数据合并到一个输出中。(基本上是一种观点)。您可以通过以下三种方式之一实现这一点:-使用模型编写视图-使用finderQuery自定义查询创建HABTM-或在model@TravisLeleu:你是说如果我用$this->query(…)为MySQL编写一个与PostgreSQL不兼容的查询,它会使该查询具有可比性吗@cdburgess:你能给我指出一些finderQuery的好例子吗?你说得对——表之间存在关系。但是我很惊讶“joins”在其他join之前创建了join。bancer,你可以参考我在答案中提供的HABTM链接,但基本上网站上是这么说的:finderQuery、deleteQuery、insertQuery:完整的SQL查询CakePHP可以用来获取、删除或创建新的关联模型记录。这应该在需要非常定制的结果的情况下使用。您可以将其放在LevelOne模型中,并让它参考LevelThree模型,以便正常工作。您最好将其作为一个视图写入数据库,然后仅为该视图创建一个模型。此外,还有一种行为可以使用连接替换Containable。奇怪的是,CakePHP没有在自定义联接之前联接绑定的模型。
public function selectdata(){
$option= $this->Group->find('all',
array(
'joins' =>
array(
array(
'table'=> 'user_groups',
'alias'=>'g',
'type'=> 'INNER',
'conditions'=> array('g.group_id =Group.id ')
),
array(
'table'=> 'users',
'alias'=>'u',
'type'=> 'INNER',
'conditions'=> array('u.id = g.user_id')
),
),'fields'=>array('Group.name,Group.created,Group.modified,Group.status,Group.created_by,u.first_name,u.last_name'),
'conditions'=>array('g.group_id=Group.created_by or g.user_id=u.id')
// ."'".$created_by."'"
)
);
var_dump($option);//die();
if(isset($this->params['requested']))
{
return $option;
}
$this->set('groups', $option);
}