1

EntitiesTable与自身有一个 belongsToMany 关联:

class EntitiesTable extends AppTable
{
    public function initialize(array $config) {
        parent::initialize($config);
        
        $this->belongsTo('Users');
        $this->hasMany('Information');
        $this->belongsToMany('LinkedEntities', array(
            'className' => 'Entities',
            'through' => 'Links',
            'foreignKey' => 'from_id',
            'targetForeignKey' => 'to_id'
        ));
        $this->belongsToMany('Tags');
    }
}

然而,这种关联只在一个方向上起作用。当表links只包含一个条目[from_id: 1, to_id: 2]时,$this->Entities->findById(1)->contain('LinkedEntities')正确地获取链接的实体,但$this->Entities->findById(2)->contain('LinkedEntities')没有。

一种解决方案是复制表中的每个条目links并交换from_idto_id,但这是不可取的。我更希望一个 belongsToMany 关联考虑from_idasforeignKeyto_idas targetForeignKey,反之亦然。

如何实现双向的 belongsToMany 自关联?

一个例子

考虑以下类似图的网络:

图形

每个点都有一个id可能还有一些附加信息(如标题或坐标)并存储在 table 中entities

现在可以使用表格来表示点之间的连接links

from_id     to_id
1           2
1           4
1           6
2           3
3           5
3           7
4           5
4           6
5           7

请注意,每个连接只存在一次,1-2 也可以像 2-1 一样存储,从到到的方向无关紧要。

现在,如果我想让所有节点都连接到节点 1,我可以使用以下查询:

SELECT * FROM entities WHERE id IN (
    SELECT to_id FROM links WHERE from_id = 1
) OR id IN (
    SELECT from_id FROM links WHERE to_id = 1
)

看看这有多容易?我只需要确保检查两个方向,因为连接是双向的。

我希望在 CakePHP 中映射这个关联。我知道这很可能目前是不可能的,这就是我在 CakePHP github 中打开一个问题的原因。

4

1 回答 1

0

这有帮助吗?

$this->belongsToMany('LinkedEntities', [
    'className' => 'Entities',
    'through' => 'links',
    'conditions' => [
         'OR' => [
                'AND' =>['Links.from_id = LinkedEntities.id', 'Links.to_id = Entities.id'],
                'AND' => ['Links.to_id = LinkedEntities.id', 'Links.from_id = Entities.id']
            ],
    ],
]);

把这个放在里面EntitiesTable

于 2015-10-11T10:22:09.197 回答