Specifying the foreign keys in a belongsToMany-through association

时间:2015-10-06 08:32:12

标签: cakephp orm foreign-keys cakephp-3.0

I want to set the used foreign keys when using a belongsToMany-through association in CakePHP 3.0.

Consider the following two tables:

entities: id, title
links: id, from_id, to_id, additional_information

I am using a belongsToMany-through association because of the additional information I need to store in the through-table.

Here are the two Table classes:

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'
        ]);
    }
}

But of course CakePHP tries to join the tables using the default foreign key entity_id, which is not correct.

How can I define the foreign keys used to join the tables in the EntitiesTable class?

Edit: For completeness' sake, here are the error message and generated query when trying to fetch an Entity with association using $this->Entities->findById(1)->contain('Entities');.

Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Links.entity_id' in 'field list'

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)

There are some additional fields in the generated queries that I stripped out of the code examples above, in case you are wondering.

1 个答案:

答案 0 :(得分:1)

在深入研究一些测试用例之后,我在this test中找到了答案。

方法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');

访问链接的实体