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')しません。

1 つの解決策は、テーブル内のすべてのエントリを複製してとlinksを交換することですが、これは望ましくありません。私はむしろ、 asとasおよびその逆を考慮して、begsToMany アソシエーションを望んでいます。from_idto_idfrom_idforeignKeyto_idtargetForeignKey

双方向の 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 でマップします。私はこれが現在不可能である可能性が非常に高いことを知っています.

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 に答える