如何过滤 CakePHP 中的深层关联
我有以下表格:活页夹、文档、用户、docs_users。 Doc 属于 Binder,Doc hasAndBelongsToMany User。
我想获取当前登录用户的活页夹及其关联文档(docs_users 表中的关联 user_id)。
我尝试过 Containable 和 find('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')
)
)
)
)
);
I have the following tables: binders, docs, users, docs_users. Doc belongsTo Binder, Doc hasAndBelongsToMany User.
I want to get binders and their associated docs for the user that is currently logged in (the associated user_id in the docs_users table).
I have tried Containable and find('all') with joins, conditions, etc. but I can't figure out how to remove the Docs that are from Users who are not associated in the docs_users table.
This code does NOT work:
$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);
And neither does this:
$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');
Any help from you seasoned pros would be great! Thanks!
Alternative/Simplified Solutions?
This works if I just want to get binders to which users have permissions. Short and sweet. However, it will still send ALL associated docs through, which is NOT the behavior I want. It needs to only pass on the docs to which the user has permissions (as described previously).
$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')
)
)
)
)
);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
以下是一些可用于在 CakePHP 中对数据进行深入查找的选项:
These are a few of the options available for doing deep finds on data in CakePHP:
这是我根据收到的所有反馈提出的最终解决方案。我认为这是一个优雅的解决方案,可以在任何需要深度关联的场景中重复使用。
在binder_controller中,我取消了Doc模型的绑定,并使用finderQuery将其绑定回来,以仅选择用户有权查看的文档。然后在加入的binders_users表中仅选择用户有权访问的活页夹。
感谢大家的帮助!
有关 绑定/解除绑定模型
Here's the final solution I came up with based on all of the great feedback I got. I think this is an elegant solution that can be reused in any scenario where deep associations are required.
In the binder_controller I unbound the Doc model, and bound it back using the finderQuery to select only the Docs that a user has permission to see. Then in joined the binders_users table selecting only the binders that users have permissions to.
Thank you everyone for all your help!
More on binding/unbinding models
在这一行中,您需要告诉 Cake 您正在谈论哪个模型的 id:
例如
DocsUser.id
...并且您不使用可包含的递归。摆脱它。
On this line, you need to tell Cake which Model's id you are talking about:
e.g.
DocsUser.id
...and you don't use recursive with containable. Get rid of it.
您是否尝试过从用户角度切入?
无论如何,应该检测到“DocsUser”关联。
从活页夹的角度来看,也许
在你的活页夹模型中添加(请检查表、键和模型名称,以防我打错字)
然后在你的活页夹控制器中尝试
有什么好处吗?
Have you tried coming in from a user perspective?
The 'DocsUser' association should be detected anyway.
From a Binders perspective maybe
In your Binders MODEL add ( please check table, key and model names in case I made a typo )
Then in your binders CONTROLLER try
Any good?