CakePHP3.4:不明白保存belongsToMany关联的错误

时间:2017-04-24 17:46:32

标签: cakephp-3.4

我尝试在表单中输入belongsToMany关联,但这是一个非常特殊的关联描述 因为我的实体Site可以将语言用于2种不同的用法,所以我使用2个连接表 架构如下

Relationship                        Join Table Fields
Sites belongsToMany Vislanguages    sites_vislanguages.id, sites_vislanguages.language_id, sites_vislanguages.site_id
Relationship                        Join Table Fields
Sites belongsToMany Reclanguages    sites_reclanguages.id, sites_reclanguages.language_id, sites_reclanguages.site_id

所以Table类是:

class VislanguagesTable extends Table {

    public function initialize(array $config) {
        parent::initialize($config);

        $this->table('languages');
        $this->displayField('name_fr');
        $this->primaryKey('id');

        $this->belongsToMany('Sites', [
            'foreignKey' => 'language_id',
            'targetForeignKey' => 'site_id',
            'joinTable' => 'sites_vislanguages',
        ]);

    }
}

class SitesTable extends Table {

public function initialize(array $config) {
    parent::initialize($config);

    $this->belongsToMany('Reclanguages', [
        'joinTable' => 'sites_reclanguages',
        'className' => 'Languages',
        'propertyName' => 'reclanguages'
    ]);

    $this->belongsToMany('Vislanguages', [
        'joinTable' => 'sites_vislanguages',
        'className' => 'Languages',
        'propertyName' => 'vislanguages'
    ]);

}

class SitesVislanguagesTable扩展了表格{

public function initialize(array $config) {
    parent::initialize($config);

    $this->table('sites_vislanguages');
    $this->displayField('id');
    $this->primaryKey('id');

    $this->belongsTo('Sites', [
        'foreignKey' => 'site_id',
    ]);
    $this->belongsTo('Languages', [
        'foreignKey' => 'language_id',
    ]);
}

我当然对addedit表单存在问题,但我这里以edit为例。 如果我find()已准备好site,则数据结构为:

object(App\Model\Entity\Site) {

    'id' => (int) 23098,
    'Vislanguages' => [
        (int) 0 => object(App\Model\Entity\Language) {

            'id' => (int) 1,
            '_joinData' => object(App\Model\Entity\SitesVislanguage) {

                'id' => (int) 4409,
                'site_id' => (int) 23098,
                'language_id' => (int) 1,
                ...,
                '[repository]' => 'SitesVislanguages'

            },
            ...,
            '[repository]' => 'Vislanguages'

        },
        (int) 1 => object(App\Model\Entity\Language) {

            'id' => (int) 9,
            '_joinData' => object(App\Model\Entity\SitesVislanguage) {

                'id' => (int) 4410,
                'site_id' => (int) 23098,
                'language_id' => (int) 9,
                ...,
                '[repository]' => 'SitesVislanguages'

            },
            ...,
            '[repository]' => 'Vislanguages'

        }
    ],
    ...,
    '[repository]' => 'Sites'

}

我相应的ctp文件是:

<?= $this->Form->control('vislanguages._ids', ['options' => $languages, 'label' => __('Spoken languages:'), 'multiple' => true]); ?>

在输入中正确预选了语言。 如果我在没有任何更改的情况下提交,修补后的实体是:

对象(App \ Model \ Entity \ Site){

'id' => (int) 23098,
...,
'vislanguages' => [
    (int) 0 => object(App\Model\Entity\Language) {

        'id' => (int) 1,
        ...,
        '[repository]' => 'Vislanguages'

    },
    (int) 1 => object(App\Model\Entity\Language) {

        'id' => (int) 9,
        ...,
        '[repository]' => 'Vislanguages'

    }
],
'[repository]' => 'Sites'

}

这似乎是正确的但是当我保存它时,我收到以下错误:

Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'vislanguage_id' in 'where clause' 

查询是:

(SELECT SitesVislanguages.id AS `SitesVislanguages__id`, SitesVislanguages.site_id AS `SitesVislanguages__site_id`, SitesVislanguages.language_id AS `SitesVislanguages__language_id` FROM sites_vislanguages SitesVislanguages WHERE (site_id = :c0 AND vislanguage_id = :c1))
UNION (SELECT SitesVislanguages.id AS `SitesVislanguages__id`, SitesVislanguages.site_id AS `SitesVislanguages__site_id`, SitesVislanguages.language_id AS `SitesVislanguages__language_id` FROM sites_vislanguages SitesVislanguages WHERE (site_id = :c2 AND vislanguage_id = :c3))

为什么我们在vislanguage_id子句中看到WHERE,而在language_id子句中却正确地考虑了SELECT

与此同时,我并不真正理解UNION

1 个答案:

答案 0 :(得分:0)

要使其正常运行,我必须指定targetForeignKey

class SitesTable extends Table {

public function initialize(array $config) {
    parent::initialize($config);

    $this->belongsToMany('Reclanguages', [
        'targetForeignKey' => 'language_id,
        'joinTable' => 'sites_reclanguages',
        'className' => 'Languages',
        'propertyName' => 'reclanguages'
    ]);

    $this->belongsToMany('Vislanguages', [
        'targetForeignKey' => 'language_id,
        'joinTable' => 'sites_vislanguages',
        'className' => 'Languages',
        'propertyName' => 'vislanguages'
    ]);

}
相关问题