如何过滤CakePHP中的深层关联

5 cakephp cakephp-1.3

我有以下表格:binders,docs,users,docs_users.Doc belongsTo Binder,Doc hasAndBelongsToMany User.

我想为当前登录的用户(docs_users表中的关联user_id)获取绑定器及其关联的文档.

我尝试过Containable并找到('all')连接,条件等,但我无法弄清楚如何从docs_users表中没有关联的用户中删除Docs.

此代码不起作用:

$binders = $this->Binder->find( 
        'all',                  
        array( 
            'joins' => array(
                array( 
                    'table' => 'binders_users', 
                    'alias' => 'BindersUser', 
                    'type' => 'inner', 
                    'foreignKey' => false, 
                    'conditions'=> array(
                        'BindersUser.binder_id = Binder.id',
                        'BindersUser.user_id = ' . $this->Auth->user('id')
                    )
                ),
                array( 
                    'table' => 'docs', 
                    'alias' => 'Doc', 
                    'type' => 'left', 
                    'foreignKey' => false, 
                    'conditions'=> array(
                        'Doc.binder_id = Binder.id',
                    )
                ),                          
                array( 
                    'table' => 'docs_users', 
                    'alias' => 'DocsUser', 
                    'type' => 'left', 
                    'foreignKey' => false, 
                    'conditions'=> array(
                        'DocsUser.doc_id = Doc.id',
                        'DocsUser.user_id = ' . $this->Auth->user('id')
                    )
                )           
            ),
            'recursive'=>0
        )
    );
$this->set('binders', $binders);
Run Code Online (Sandbox Code Playgroud)

这也不是:

$this->Binder->recursive = 2;
$this->Binder->Behaviors->attach('Containable');
$this->Binder->contain(array(
    'Branch',
    'Doc' => array(                     
        'User' => array(
            'DocsUser' => array(
                'conditions' => array('id = "17"')
            )
        )
    )
));
$binders = $this->Binder->find('all');
Run Code Online (Sandbox Code Playgroud)

经验丰富的职业选手的任何帮助都会很棒!谢谢!

替代/简化解决方案?

如果我只想获取用户具有权限的绑定器,则此方法有效.简短又甜蜜.但是,它仍会发送所有关联的文档,这不是我想要的行为.它只需要传递用户具有权限的文档(如前所述).

$binders = $this->Binder->find( 
    'all',                  
    array( 
        'joins' => array(
            array( 
                'table' => 'binders_users', 
                'alias' => 'BindersUser', 
                'type' => 'inner', 
                'foreignKey' => false, 
                'conditions'=> array(
                    'BindersUser.binder_id = Binder.id',
                    'BindersUser.user_id = ' . $this->Auth->user('id')
                )
            )
        )
    )
);
Run Code Online (Sandbox Code Playgroud)

小智 4

这是我根据收到的所有反馈提出的最终解决方案。我认为这是一个优雅的解决方案,可以在任何需要深度关联的场景中重复使用。

在binder_controller中,我取消了Doc模型的绑定,并使用finderQuery将其绑定回来,以仅选择用户有权查看的文档。然后在加入的binders_users表中仅选择用户有权访问的活页夹。

感谢大家的帮助!

$this->Binder->unbindModel(array('hasMany' => array('Doc')));
$this->Binder->bindModel(
    array('hasMany' => array(
            'Doc' => array(
                'className' => 'Doc',
                'foreignKey' => 'binder_id',
                'dependent' => false,
                'finderQuery' => 'SELECT Doc.* FROM docs AS Doc INNER JOIN docs_users AS DocsUser ON DocsUser.doc_id = Doc.id AND DocsUser.user_id = ' . $this->Auth->user('id')
            )
        )
    )
);

$binders = $this->Binder->find( 
    'all',                  
    array( 
        'joins' => array(
            array( 
                'table' => 'binders_users', 
                'alias' => 'BindersUser', 
                'type' => 'inner', 
                'foreignKey' => false, 
                'conditions'=> array(
                    'BindersUser.binder_id = Binder.id',
                    'BindersUser.user_id = ' . $this->Auth->user('id')
                )
            )               
        )
    )
);
Run Code Online (Sandbox Code Playgroud)

有关绑定/解除绑定模型的更多信息