CakePHP 3 跨 2 个表保存关联数据
Posted
技术标签:
【中文标题】CakePHP 3 跨 2 个表保存关联数据【英文标题】:CakePHP 3 saving associated data across 2 tables 【发布时间】:2017-01-30 11:40:15 【问题描述】:更新:从表单输入中删除 0 并从会话中删除 s,同时还将关系从 Booking hasMany Sessions 更改为 Booking hasOne Session。
所以我有 4 个与此相关的表:
预订(带有输入字段的表单的来源) 会话(链接到预订) Sessionplayers_sessions(Sessionplayers 和 Sessions 之间的连接表) 会话播放器当使用我的表单时,我会尝试保存 Bookings、Sessions 和 Sessionplayer_sessions。下面的表单输入是 Sessionplayer_sessions 的唯一相关字段:
<?php echo $this->Form->input('session.sessionplayers._ids', ['type' => 'select', 'options'=>'','multiple']); ?>
表单输入中的选项显示为空白,来自一个允许选择多个项目的双列表 jQuery 脚本。
但是,当我尝试保存时,上述输入中的任何内容实际上都没有发布到 Sessionplayer_sessions 表中,而 Bookings & Sessions 中的所有内容都已成功发布。
在控制器中,newEntity 和 patchEntity 部分如下所示:
$booking = $this->Bookings->newEntity($this->request->data(),[
'associated'=>[
'Sessions' => ['associated' => ['Guestengineers', 'Sessionplayers']]
]]);
if($this->request->is('post'))
$data = $this->request->data;
$booking = $this->Bookings->patchEntity($booking, $data, [
'associated'=>[
'Sessions' => ['associated' => ['Guestengineers', 'Sessionplayers']]
]
]);
以及 Sessions 和 Sessionplayers 表的各自模型:
会话:
public function initialize(array $config)
parent::initialize($config);
$this->table('sessions');
$this->displayField('id');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongstoMany('Sessionplayers', [
'foreignKey' => 'session_id',
'targetForeignKey' => 'sessionplayer_id',
'joinTable' => 'Sessionplayers_sessions'
]);
会话玩家:
public function initialize(array $config)
parent::initialize($config);
$this->table('sessionplayers');
$this->displayField('id');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongstoMany('Sessions', [
'foreignKey' => 'sessionplayer_id',
'targetForeignKey' => 'session_id',
'joinTable' => 'Sessionplayers_sessions'
]);
结果:
在更新表单输入和 Bookings & Sessions 表之间的关系并重新提交时:
在 post 数据中,sessionplayers 现在是 session 数组中的一个数组。 sessionplayers 数组内部有一个属性:_ids,其值引用在表单输入的多选中选择的第一个 sessionplayer 的 id - 例如,如果我选择了第 3 个 sessionplayer 和第 4 个 sessionplayer,_ids = 3。但是,在数据库本身中,虽然能够成功插入 bookings 和 sessions 表数据,但 sessionplayers_session 的表却没有。
基本上:请求数据数组如下:Session(array) -> Sessionplayers(array) -> _ids = 3。
在 SQL 日志中,只发生了两条 Insert Into SQL 语句,一条用于 Bookings,一条用于 Sessions。 Sessionplayers_sessions 没有这样的插入。
【问题讨论】:
0
看起来放错了位置。神奇的_ids
键应该直接连接到关联属性名称。另外,请始终尝试进行一些调试,因为基本上只是“不起作用”的问题通常被认为是题外话。在您的情况下,检查您的控制器中的请求数据和修补实体的确切外观可能最相关。
哦,我做到了。提交后,在请求中,连接表的属性不存在于帖子数据中。我还尝试了 Cookbook 的多对多关联选项,但没有区别。当您说 0 放错位置时,0 通常意味着相对于关联表去哪里?
我并不是只想说做一些调试,而是特别指出结果应该在你的问题中。我想说0
在你的情况下根本不应该存在,_ids
键应该直接连接到sessionplayers
。查看文档中的示例:book.cakephp.org/3.0/en/orm/…
在删除 0 并更改 bookings 和 sessions 表之间的关系后,用结果更新了我的帖子。
我想我设法修复了它 - 我在 _ids 之后添加了一个数组 [],它们似乎已正确保存,尽管我在保存时确实收到了几个警告。
【参考方案1】:
我想我在从表单输入中删除 0 并将关系从 OneToMany 更改为 OneToOne 后设法修复它,方法是添加 [] 以表示可能有多个项目被选中。
【讨论】:
以上是关于CakePHP 3 跨 2 个表保存关联数据的主要内容,如果未能解决你的问题,请参考以下文章
CakePHP 3:上传多个文件并将文件名保存在关联模型中?