使用hasMany关联保存数据时出现问题
这是我的表
1)发布表:每个项目都有唯一的ID。
id | title | ...
1 | Aloha | ...
2)图像表
id | post_id | image | ...
1 | 1 | abc.jpg | ...
2 | 1 | efg.jpg | ...
我的模型(表格)
帖子模型
// PostsTable.php
<?php
namespace App\Model\Table;
use Cake\ORM\Query;
use Cake\ORM\Table;
use Cake\Validation\Validator;
class PostsTable extends Table {
public function initialize(array $config) {
$this->table('posts');
$this->displayField('title');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->hasMany('Images', [
'foreignKey' => 'id'
]);
}
}
...
图片型号
// ImagesTable.php
<?php
namespace App\Model\Table;
use Cake\ORM\Query;
use Cake\ORM\Table;
use Cake\Validation\Validator;
class ImagesTable extends Table {
public function initialize(array $config) {
$this->table('images');
$this->displayField('id');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('Posts');
}
}
...
我的控制器
// PostsController.php
...
public function add() {
$post = $this->Posts->newEntity($this->request->data, [
'associated' => ['Images']
]);
if ($this->request->is('post')) {
if ($this->Posts->save($post, ['associated' => ['Images']])) {
$this->Flash->success('The post has been saved.');
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error('The post could not be saved. Please, try again.');
}
}
$this->set('post', $post);
}
...
我的模板
// add.ctp
<?= $this->Form->create($post); ?>
<?php echo $this->Form->input('title'); ?>
<?php echo $this->Form->input('images.0.image'); ?>
<?php echo $this->Form->input('images.1.image'); ?>
<?php echo $this->Form->input('images.2.image'); ?>
<?= $this->Form->button(__('Submit'), ['class' => 'button-green']) ?>
<?= $this->Form->end() ?>
输入数组结果Debug
[
'title' => 'Hello',
'images' => [
(int) 0 => [
'image' => 'testa.jpeg'
],
(int) 1 => [
'image' => 'testb.jpeg'
],
(int) 2 => [
'image' => 'testc.jpeg'
]
]
]
(更新) 的 调试($交)
object(App\Model\Entity\Story) {
'new' => true,
'accessible' => [
'title' => true,
'images' => true
],
'properties' => [
'title' => 'Hello',
'images' => [
(int) 0 => object(App\Model\Entity\Image) {
'new' => true,
'accessible' => [
'post_id' => true,
'image' => true,
'post' => true
],
'properties' => [
'image' => 'testa.jpeg'
],
'dirty' => [
'image' => true
],
'original' => [],
'virtual' => [],
'errors' => [],
'repository' => 'Images'
},
(int) 1 => object(App\Model\Entity\Image) {
'new' => true,
'accessible' => [
'post_id' => true,
'image' => true,
'post' => true
],
'properties' => [
'image' => 'testb.jpeg'
],
'dirty' => [
'image' => true
],
'original' => [],
'virtual' => [],
'errors' => [],
'repository' => 'Images'
},
(int) 2 => object(App\Model\Entity\Image) {
'new' => true,
'accessible' => [
'post_id' => true,
'image' => true,
'post' => true
],
'properties' => [
'image' => 'testc.jpeg'
],
'dirty' => [
'image' => true
],
'original' => [],
'virtual' => [],
'errors' => [],
'repository' => 'Images'
}
]
],
'dirty' => [
'title' => true,
'images' => true
],
'original' => [],
'virtual' => [],
'errors' => [],
'repository' => 'Stories'
}
我无法弄清楚我做错了什么
由于
答案 0 :(得分:2)
我没有查看所有内容,但我看到您的关联声明中存在错误:
$this->hasMany('Images', [
'foreignKey' => 'id'
]);
文档说:
foreignKey:在其他模型中找到的外键的名称。如果您需要定义多个hasMany关系,这将特别方便。此键的默认值是实际模型的下划线,单数名称,后缀为“_id”。
所以它应该是:
$this->hasMany('Images', [
'foreignKey' => 'post_id'
]);
甚至:
$this->hasMany('Images');
答案 1 :(得分:2)
我刚刚完成了3小时的巡演,并保存了很多内容以及主模型。如果考虑用许多相关项目保存许多主要模型的对象,那么这种斗争似乎更加糟糕。
hasMany关系中的外键是具有_id后缀的当前模型(实体)的单数名称,因此它类似于:
class MainModel extends Table {
...
public function initialize(array $config) {
...
// remember the "s" at the end of the name
$this->hasMany('VeryWeirdCalleds', [
'className' => 'VeryWeirdCalleds',
'foreignKey' => 'main_model_id',
'propertyName' => 'very_weird_calleds'
]);
...
}
...
}
然后,在MAIN实体中设置accessible,以便MAIN模型可以根据“very_weird_calleds”索引保存关联:
class MainModel extends Entity {
protected $_accessible = [
...
'very_weird_calleds' => true,
];
}
最后(但并非最不重要):Controller保存。这通常是最难克服的部分,因为事实上,文档并没有详细阐明整个过程:
class MainModelsController extends AppController {
public function add($data) {
$data = [
[
'name' => 'Hello',
'body' => 'Bla bla',
'very_weird_calleds' => [
[
'name' => 'Very Weird Called'
]
]
]
];
foreach ($data as $record) {
$main = $this->MainModels->newEntity($record);
if(isset($record['images']) && !empty($record['images'])) {
foreach($record['images'] as $record_image) {
$image = $this->MainModels->VeryWeirdCalleds->newEntity();
$image->IMAGE = $record_image['IMAGE'];
$import->very_weird_calleds[] = $image;
}
}
if (!$this->MainModels->save($main)) {
$this->Flash->error('The main model could not be saved. Please, try again.');
}
}
}
解释?首先,我们循环遍历以前准备的数据:
['main','model','data','association_accessible_property'=&gt; ['associated_data']]]
然后,我们使用与主模型相同的方法为关联数据创建新条目。最后一点是将那些关联的实体添加到主模型实体。
请特别注意此示例中给出的名称。 's'-es和CamelCases不是巧合。
答案 2 :(得分:1)
试试这个:
<?php echo $this->Form->input('0.Images.image'); ?>
<?php echo $this->Form->input('1.images.image'); ?>
<?php echo $this->Form->input('2.images.image'); ?>
以前使用int,根据http://book.cakephp.org/3.0/en/views/helpers/form.html#field-naming-conventions