此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
为foreignKey
而to_id
为targetForeignKey
,反之亦然。
如何实施双向belongsToMany自我关联?
考虑以下类似图形的网络:
每个点都有一个id
,可能还有一些其他信息(如标题或坐标),并存储在表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中映射此关联。我知道这很可能是目前不可能的,这就是为什么我打开issue in the CakePHP github。
答案 0 :(得分: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