これ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')
しません。
1 つの解決策は、テーブル内のすべてのエントリを複製してとlinks
を交換することですが、これは望ましくありません。私はむしろ、 asとasおよびその逆を考慮して、begsToMany アソシエーションを望んでいます。from_id
to_id
from_id
foreignKey
to_id
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 回だけ存在することに注意してください。1-2 は 2-1 と同じように保存できます。from-to の方向は関係ありません。
ここで、ノード 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 でマップします。私はこれが現在不可能である可能性が非常に高いことを知っています.