在 CakePHP 3 中保存多个 belongsToMany 关联

Posted

技术标签:

【中文标题】在 CakePHP 3 中保存多个 belongsToMany 关联【英文标题】:Saving multiple belongsToMany associations in CakePHP 3 【发布时间】:2014-12-31 23:12:44 【问题描述】:

首先让我解释一下我想要实现的目标。

3个mysql表与这个问题有关:

预设:

id | name | description | user_id | ...

文件:

id | name | size | ...

文件预设

id | file_id | preset_id | original_image (bool) | small_thumb (bool) | big_thumb (bool) | file (bool)

我正在此网站上构建一个用于创建预设的表单。 Preset 由以下部分组成:

3张图片:一张original_image,一张small_thumb和一张big_thumb,都存储在files表中 未知数量的文件,也存储在files 表中 presets 表中存储的其他信息

所有文件都是预先通过 AJAX 上传的,所以当提交表单时,所有文件都已经在数据库中,并且它们的 ID 与所有预设信息一起通过隐藏输入发送。

files_presets 表是我用来将每个预设链接到其文件和图像的表。 original_image、small_thumb、big_thumb 和 file 列是布尔值,指示每个文件对预设的含义。

所以,这就是我在PresetsTable.php 文件中定义我的关联的方式:

    $this->belongsToMany('OriginalImage', [
        'through' => 'FilesPresets',
        'className' => 'Files',
        'property_name' => 'original_image',
        'foreignKey' => 'preset_id',
        'targetForeignKey' => 'file_id',
        'conditions' => ['FilesPresets.original_image' => true]
    ]);
    $this->belongsToMany('SmallThumb', [
        'through' => 'FilesPresets',
        'className' => 'Files',
        'property_name' => 'small_thumb',
        'foreignKey' => 'preset_id',
        'targetForeignKey' => 'file_id',
        'conditions' => ['FilesPresets.small_thumb' => true]
    ]);
    $this->belongsToMany('BigThumb', [
        'through' => 'FilesPresets',
        'className' => 'Files',
        'property_name' => 'big_thumb',
        'foreignKey' => 'preset_id',
        'targetForeignKey' => 'file_id',
        'conditions' => ['FilesPresets.big_thumb' => true]
    ]);
    $this->belongsToMany('Files', [
        'through' => 'FilesPresets',
        'className' => 'Files',
        'property_name' => 'files',
        'foreignKey' => 'preset_id',
        'targetForeignKey' => 'file_id',
        'conditions' => ['FilesPresets.file' => true]
    ]);

这样我可以获取与预设相关的所有图像和文件,执行类似的操作(这里没有任何问题):

    $preset = $this->Presets->get($id, [
        'contain' => [
            'OriginalImage', 'SmallThumb', 'BigThumb', 'Files'
        ]
    ]);

问题是:

尝试保存此数据时出现各种错误。

我需要做什么:

将所有基本信息保存到presets 表(名称、描述等) 在files_presets 表中为每个文件创建一条记录,将它们链接到刚刚创建的预设,同时保存其他信息(布尔列)

请记住,我不想在files 表中创建新记录,因为文件已经在数据库中并且我有它们的 ID。我只想将他们的 ID 与新预设相关联。

提前感谢您帮助我, 丹尼尔。

【问题讨论】:

你已经解释了这一切都很好,但最重要的是,实际的错误和用于保存的代码都不见了。 嗨,丹尼尔,您找到解决问题的方法了吗? 【参考方案1】:

您可能想尝试的一件事是使用别名而不是类名:

$this->belongsToMany('OriginalImage', [
    'through' => 'FilesPresets',
    'className' => 'Files',
    'property_name' => 'original_image',
    'foreignKey' => 'preset_id',
    'targetForeignKey' => 'file_id',
    'conditions' => ['OriginalImage.original_image' => true] // <-- Changed `FilePresets` to `OriginalImage` alias.
]);

当 Cake 生成 SQL 时,它使用别名而不是底层的 className,以避免与同一个目标表的多个关联之间的冲突。

【讨论】:

以上是关于在 CakePHP 3 中保存多个 belongsToMany 关联的主要内容,如果未能解决你的问题,请参考以下文章

CakePHP 3.x:将一个输入保存到多个表中

Cakephp 3.x 保存 hasmany 关联

cakephp 3.0 - 保存独特的关联

CakePHP:将数据保存到 3 个不同的模型

cakePHP 保存到多个模型

CakePHP 1.3 - 保存不相关模型的事务