Это EntitiesTable
имеет ассоциацию belongsToMany с собой:Двунаправленного 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
и наоборот.
Как можно реализовать двунаправленную принадлежность?
Пример
Рассмотрим следующий график, как сеть:
Каждая точка имеет 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.
: http://stackoverflow.com/q/20832098/2580794 Решение есть работает только для старых версий CakePHP, так как вариант 'finderQuery' был удален , –
Попробуйте найти объекты по $ id и добавьте условия для сдерживаемых LinkedEntities. WHERE is from_id = $ id OR to_id = $ id http://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets. html # pass-conditions-to-содержать – Salines
Добавление дополнительных условий ограничивает связанные объекты далее, так как в результате запроса все равно требуется, чтобы to_id был $ id. –