这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_id
和to_id
,但这是不可取的。我更希望一个 belongsToMany 关联考虑from_id
asforeignKey
和to_id
as 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 中打开一个问题的原因。