我有以下表格:binders,docs,users,docs_users。 Doc belongsTo Binder,Doc hasAndBelongsToMany User。
我想为当前登录的用户(docs_users表中的关联user_id)获取活页夹及其相关文档。
我尝试过Containable并找到('all')连接,条件等,但我无法弄清楚如何从docs_users表中没有关联的用户中删除文档。
此代码不起作用:
$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);
这两点都没有:
$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');
经验丰富的专业人士的任何帮助都会很棒!谢谢!
替代/简化解决方案?
如果我只想获取用户具有权限的绑定器,则此方法有效。简短又甜蜜。但是,它仍会发送所有关联的文档,这不是我想要的行为。它只需要传递用户具有权限的文档(如前所述)。
$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')
)
)
)
)
);
答案 0 :(得分:5)
这些是可用于对CakePHP中的数据进行深层查找的一些选项:
答案 1 :(得分: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')
)
)
)
)
);
答案 2 :(得分:0)
在这一行上,你需要告诉Cake你正在谈论哪个模型:
'conditions' => array('id = "17"')
e.g。 DocsUser.id
...并且您不使用withable的递归。摆脱它。
答案 3 :(得分:0)
您是否尝试过从用户的角度出发?
$this->Binder->Doc->User->Behaviors->attach('Containable');
$this->Binder->Doc->User->contain(array('Doc'=>'Binder'));
$user = $this->Binder->Doc->User->find('all',array('conditions'=>'User.id'=>$user_id));
无论如何都应该检测'DocsUser'关联。
从Binders角度来看可能
在您的Binders MODEL中添加(如果我输错了,请查看表格,密钥和型号名称)
function getBindersByUserSql($user_id)
{
$dbo = $this->getDataSource();
$subQuery = $dbo->buildStatement(
array(
'fields' => array('DISTINCT(Doc.binder_id)'),
'table' => "docs_users",
'joins' => array(
array('table' => 'users',
'alias' => 'User',
'type' => 'INNER',
'conditions' => array('DocsUser.user_id = User.id')
),
array('table' => 'docs',
'alias' => 'Doc',
'type' => 'INNER',
'conditions' => array('Doc.id = DocsUser.doc_id')
)
),
'alias'=>"DocsUser",
'conditions' => array("User.id"=>$user_id),
'order' => null,
'group' => "Doc.binder_id"
),
$this
);
return $dbo->expression($subQuery);
}
然后在你的活页夹中使用CONTROLLER试试
$this->Binder->Behaviors->attach('Containable');
$this->Binder->contain(array('Doc'));
$conditions = array();
$conditions = $this->Binder->getBindersByUserSql($this->Auth->user('id'));
$binders = $this->Binder->find('all',array('conditions'=>$conditions)));
有什么好处吗?