Указание внешних ключей в ассоциации ownToMany-through

Я хочу установить используемые внешние ключи при использовании ассоциации ownToMany-through в CakePHP 3.0.

Рассмотрим следующие две таблицы:

entities: id, title
ссылки: id, from_id, to_id, Additional_information

Я использую сквозную ассоциацию ownToMany из-за дополнительной информации, которую мне нужно хранить в сквозной таблице.

Вот два класса таблицы:

class LinksTable extends AppTable
{
    public function initialize(array $config) {
        parent::initialize($config);

        $this->belongsTo('FromEntities', [
            'className' => 'Entity',
            'foreignKey' => 'from_id'
        ]);
        $this->belongsTo('ToEntities', [
            'className' => 'Entity',
            'foreignKey' => 'to_id'
        ]);
    }
}

class EntitiesTable extends AppTable
{
    public function initialize(array $config) {
        parent::initialize($config);

        $this->belongsToMany('Entities', [
            'through' => 'Links'
        ]);
    }
}

Но, конечно же, CakePHP пытается присоединиться к таблицам, используя внешний ключ по умолчанию entity_id, что неверно.

Как определить внешние ключи, используемые для соединения таблиц в классе EntitiesTable?

Изменить. Для полноты картины приведем сообщение об ошибке и сгенерированный запрос при попытке получить объект с ассоциацией с помощью $this->Entities->findById(1)->contain('Entities');.

Ошибка: SQLSTATE [42S22]: столбец не найден: 1054 Неизвестный столбец «Links.entity_id» в «списке полей»

SELECT Links.entity_id AS `Links__entity_id`, Links.id AS `Links__id`, Links.from_id AS `Links__from_id`, Links.to_id AS `Links__to_id`, Links.type AS `Links__type`, Links.role AS `Links__role`, Entities.id AS `Entities__id`, Entities.type AS `Entities__type`, Entities.title AS `Entities__title`, Entities.user_id AS `Entities__user_id`, Entities.created AS `Entities__created` FROM entities Entities INNER JOIN links Links ON Entities.id = (Links.entity_id) WHERE Links.entity_id in (:c0)

В сгенерированных запросах есть несколько дополнительных полей, которые я убрал из приведенных выше примеров кода, если вам интересно.


person Lars Ebert    schedule 06.10.2015    source источник


Ответы (1)


Покопавшись в нескольких тестовых примерах, я нашел ответ в этом тест.

Метод belongsToMany имеет недокументированную опцию targetForeignKey, поэтому класс EntitiesTable должен выглядеть так:

class EntitiesTable extends AppTable
{
    public function initialize(array $config) {
        parent::initialize($config);

        $this->belongsToMany('LinkedEntities', [
            'className' => 'Entities',
            'through' => 'Links',
            'foreignKey' => 'from_id',
            'targetForeignKey' => 'to_id'
        ]);
    }
}

Теперь я могу получить доступ к связанному объекту, используя $this->Entities->findById(1)->contain('LinkedEntities');

person Lars Ebert    schedule 06.10.2015