CakePHP 3.1,通用 BelongsToMany

CakePHP 3.1, universal BelongsToMany

我自己做了一个加载相关内容的插件beforeFind(),所以你可以说ContentPage/10类似于ConentNews/10Gallery/5

我的 table related_contents 看起来像:

id                  int(11)
source_table_name   varchar(255)
target_table_name   varchar(255)
source_table_id     int(11)
target_table_id     int(11)

我的行为代码:

public function beforeFind(Event $event, Query $query, ArrayObject $options, $primary) {
  $attachedTables = self::getAttachedTables(); //Array of ORM models which has this behavior
  foreach ($attachedTables as $attachedTable) {
    $options = [
      'through'    => 'RelatedContents',
      'bindingKey' => 'RelatedContents.source_table_id',
      'foreignKey' => 'RelatedContents.target_table_id',
      'conditions' => [
        'RelatedContents.source_table_name' => $this->_table->table(),
        'target_table_name' => $attachedTable->table(),
      ]
    ];
    $this->_table->belongsToMany($attachedTable->alias(), $options);
  }
}

现在,当我尝试在我的模型中 find() 时,没有错误地找到了零个相关实体。我做错了什么?

如果在初始化时调用您的 getAttachedTables() 方法导致递归,那么可能有一些问题需要修复。重新关联每个发现似乎不是一个好主意,除非你真的需要这样做,因为关联有 changed/need 改变,或已被删除。

也就是说,您的问题很可能是缺少 targetForeignKey 选项,您正在使用的 bindingKey 选项不适用于 BelongsToMany 关联!另请注意,外键需要定义为不带别名!

此外,您还缺少条件中的别名,但这与未获取任何关联的问题无关。

所以,foreignKey应该设置为当前模型中的FK列,targetForeignKey设置为目标模型的FK列,如

$options = [
    // ...
    'foreignKey'       => 'source_table_id',
    'targetForeignKey' => 'target_table_id',
    // ...
];

另见