Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何更改';联接';用CakePHP?_Php_Cakephp_Join_Model_Associations - Fatal编程技术网

如何更改';联接';用CakePHP?

如何更改';联接';用CakePHP?,php,cakephp,join,model,associations,Php,Cakephp,Join,Model,Associations,我对连接的顺序有问题。类似的问题出现在另一个问题中。答案是使用可控制的行为。在我的例子中,这是不可接受的,因为我有更深的关联,containable生成了太多的查询。Containeable不会为三级关联生成联接。它为第二级表中的每个条目生成附加查询 我的问题是: $this->LevelOne->find('all', array( 'joins' => array(array( 'table' => 'level_three',

我对连接的顺序有问题。类似的问题出现在另一个问题中。答案是使用可控制的行为。在我的例子中,这是不可接受的,因为我有更深的关联,containable生成了太多的查询。Containeable不会为三级关联生成联接。它为第二级表中的每个条目生成附加查询

我的问题是:

$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);

    }