CakePHP:如何使用同一张表设置 BelongsToMany?
Posted
技术标签:
【中文标题】CakePHP:如何使用同一张表设置 BelongsToMany?【英文标题】:CakePHP: How to setup BelongsToMany with the same table? 【发布时间】:2020-06-27 19:12:01 【问题描述】:我有一个名为 processo_administrativo 的表,它拥有并属于许多 processo_administrativo 到 processo_administrativo_processo_administrativo
两个表的 id 为“identity(1,1)”
连接表 processo_administrativo_processo_administrativo 有这些列:
processo_administrativo_id 和 processo_administrativo_associado_id 都引用了 processo_administrativo.id
所以,我在 ProcessoAdministrativoTable 上试过这个:
$this->belongsToMany('ProcessoAdministrativo', [
'targetForeignKey'=> 'processo_administrativo_associado_id',
'foreignKey'=> 'processo_administrativo_id'
])
->setThrough('ProcessoAdministrativoProcessoAdministrativo');
并尝试使用包含:
$result = $paTable->find()->contain('ProcessoAdministrativo')
->where(['id IN'=>[2947,3694]])
->toArray();
debug($result);
但是 Cake 这样做了(在第二个查询中):
....
FROM
processo_administrativo ProcessoAdministrativo
INNER JOIN processo_administrativo_processo_administrativo ProcessoAdministrativoProcessoAdministrativo ON ProcessoAdministrativo.id = (
ProcessoAdministrativoProcessoAdministrativo.processo_administrativo_id
)
WHERE
ProcessoAdministrativoProcessoAdministrativo.processo_administrativo_id in (2947, 3694)
如您所见,出于某种原因,Cakephp 只是忽略了 targetForeignKey (processo_administrativo_associado_id)。我不知道为什么。
结果是两个 ProcessoAdministrativo 实体,没有来自数据库的属性和值。
那么,建立这种关联的正确方法是什么?
【问题讨论】:
【参考方案1】:您在此处所做的操作通常会触发异常,因为您不能有两个同名的表别名,即只能有一个 ProcessoAdministrativo
,而这已经是您父表的默认别名。
如果要创建自引用关联,则需要为其创建唯一别名,并使用className
选项来引用原始表别名。
$this
->belongsToMany('ProcessoAdministrativoAssociado')
->setClassName('ProcessoAdministrativo')
->setTargetForeignKey('processo_administrativo_associado_id')
->setForeignKey('processo_administrativo_id')
->setThrough('ProcessoAdministrativoProcessoAdministrativoAssociado');
为了避免 CakePHP 期望的名称混淆和进一步的问题,我建议在需要时也相应地调整表名、类名和列名的约定,即至少也要调整 through
类名以及相应的表名 (processo_administrativo_processo_administrativo_associado
)。
此外,我建议您使用美国英语作为您的名称,因为这是用于推断表/类/键/变量/等名称的 CakePHPs 变形的基础 - 这将使您的生活更轻松!
另见
Cookbook > Database Access & ORM > Associations - Linking Tables Together Cookbook > CakePHP at a Glance > CakePHP Conventions【讨论】:
嗨,我收到此错误:错误:无法描述 processo_administrativo_processo_administrativo_associado。它有 0 列。 @celsowm 当表不存在或无法访问(例如权限问题)时,通常会发生该错误 但是名字不对,正如你在我的帖子中看到的,连接表被称为“processo_administrativo_processo_administrativo”而不是“processo_administrativo_processo_administrativo_associado” @celsowm 是也不是,processo_administrativo_processo_administrativo_associado
是按照我建议的命名约定的正确名称,它源自 through
别名/类名。我建议您相应地更改表和类名。想象一下,您要准备一些东西,以便可以添加多个自关联,为此您不可避免地需要唯一且有意义的连接表名称。
最后我做到了: $this->belongsToMany('ProcessoAssociado', [ 'className'=>'ProcessoAdministrativo' ]) ->setTargetForeignKey('processo_administrativo_associado_id') ->setForeignKey('processo_administrativo_id') ->setThrough('processo_administrativo_processo_administrativo');【参考方案2】:
解决办法是:
$this->belongsToMany('ProcessoAssociado',
[ 'className'=>'ProcessoAdministrativo' ])
->setTargetForeignKey('processo_administrativo_associado_id')
->setForeignKey('processo_administrativo_id')
->setThrough('processo_administrativo_processo_administrativo');
【讨论】:
以上是关于CakePHP:如何使用同一张表设置 BelongsToMany?的主要内容,如果未能解决你的问题,请参考以下文章
如何将“删除”操作委托给 Cakephp 4 中的另一个模型?
如何将我的表的自动增量 id 设置为 700,即使同一张表上存在 1000 条记录?