【问题标题】:CakePHP: How to setup BelongsToMany with the same table?CakePHP:如何使用同一张表设置 BelongsToMany?
【发布时间】:2020-06-27 19:12:01
【问题描述】:

我有一个名为 processo_administrativo 的表,它拥有并属于许多 processo_administrativoprocesso_administrativo_processo_administrativo

两个表的 id 为“identity(1,1)”

连接表 processo_administrativo_processo_administrativo 有这些列:

processo_administrativo_idprocesso_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 实体,没有来自数据库的属性和值。

那么,建立这种关联的正确方法是什么?

【问题讨论】:

    标签: cakephp associations has-and-belongs-to-many


    【解决方案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 变形的基础 - 这将使您的生活更轻松!

    另见

    【讨论】:

    • 嗨,我收到此错误:错误:无法描述 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');
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多