5

使用 hasMany 关联保存数据时出现问题

这是我的桌子

1)post表:每个item都有一个唯一的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() ?>

输入数组结果调试

[
   'title' => 'Hello',
   'images' => [
       (int) 0 => [
           'image' => 'testa.jpeg'
       ],
       (int) 1 => [
           'image' => 'testb.jpeg'
       ],
       (int) 2 => [
           'image' => 'testc.jpeg'
       ]
   ]
]

(更新) 调试($post)

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'

}

我不知道我做错了什么

谢谢

4

3 回答 3

2

我没有查看所有内容,但我发现您的关联声明中有一个错误:

$this->hasMany('Images', [
    'foreignKey' => 'id'
]);

文档说:

foreignKey:在其他模型中找到的外键的名称。如果您需要定义多个 hasMany 关系,这将特别方便。该键的默认值是实际模型的带下划线的单数名称,后缀为“_id”。

所以应该是:

$this->hasMany('Images', [
    'foreignKey' => 'post_id'
]);

甚至:

$this->hasMany('Images');
于 2015-03-31T16:35:17.510 回答
2

我刚刚完成了我的 3 小时游览,并保存了 hasMany 内容和主要模型。如果考虑保存许多主要模型的对象和许多相关项目,这种斗争似乎更糟。

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

然后,在主实体中设置可访问,以便主模型可以保存基于“very_weird_calls”索引的关联:

class MainModel extends Entity {
    protected $_accessible = [
        ...
        'very_weird_calleds' => true,
    ];
}

最后一个(但并非最不重要的):控制器保存。这通常是最难克服的部分,因为文档没有详细说明整个过程:

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' => ['associated_data']]]

然后我们使用与主模型相同的方法为关联数据创建新条目。最后一件事是将那些关联的实体添加到主模型实体中。

请特别注意本示例中给出的名称。's'-es 和 CamelCases 并非巧合。

于 2015-05-23T19:29:30.027 回答
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

于 2014-12-10T11:19:37.067 回答