CakePHP 3 hasMany不会将父ID传递给关联的子项

时间:2015-03-19 07:16:56

标签: cakephp-3.0

     /* ShootsTable.php Meta Table */ 

       public function initialize(array $config)
        {
            $this->table('shoots');
            $this->displayField('title');
            $this->primaryKey('id');
            $this->hasMany('ShootMeta');
        }


    /* ShootMetaTable.php Meta Table */

     public function initialize(array $config)
        {
            $this->table('shoot_meta');
            $this->displayField('id');
            $this->primaryKey('id');
            $this->belongsTo('Shoots');
        }
        public function buildRules(RulesChecker $rules)
         {
            $rules->add($rules->existsIn(['shoots_id'], 'Shoots'));
            return $rules;
         }

 /* Shoots.php Controller */

public function add()
    {
        $shoot = $this->Shoots->newEntity(null);
        if ($this->request->is('post')) {
            $this->Shoots->patchEntity($shoot, $this->request->data,[
                'associated' => ['ShootMeta']
            ]);
            $shoot->set('created_by', 1);
            debug($shoot);
            if ($this->Shoots->save($shoot,['associated' => ['ShootMeta']])) {
                $this->Flash->success('The shoot has been saved.');
               // return $this->redirect(['action' => 'index']);
            } else {
                $this->Flash->error('The shoot could not be saved. Please, try again.');
            }
        }
        $this->set(compact('shoot'));
        $this->set('_serialize', ['shoot']);
    }

 /* Add.ctp Template */

<div class="shoots form large-10 medium-9 columns">
    <?= $this->Form->create($shoot); ?>
    <fieldset>
        <legend><?= __('Add Shoot') ?></legend>
        <?php
            echo $this->Form->input('title');
            echo $this->Form->input('content');
            echo $this->Form->input('datetime', ['label' => 'Date/Time Of Shoot']);

            echo $this->Form->input('shoot_meta.0.meta_key', ['type' => 'hidden', 'value' => 'photographer_spaces']);
            echo $this->Form->input('shoot_meta.0.meta_value',['label' => 'Photographer Spaces', 'type' => 'number']);
        ?>
    </fieldset>
    <?= $this->Form->button(__('Submit')) ?>
    <?= $this->Form->end() ?>
</div>

/* debug($shoots) output */

object(App\Model\Entity\Shoot) {

    'new' => true,
    'accessible' => [
        'created_by' => true,
        'title' => true,
        'content' => true,
        'datetime' => true,
        'shoot_meta' => true
    ],
    'properties' => [
        'title' => '123',
        'content' => '123',
        'datetime' => object(Cake\I18n\Time) {

            'time' => '2015-03-19T07:04:00+0000',
            'timezone' => 'UTC',
            'fixedNowTime' => false

        },
        'shoot_meta' => [
            (int) 0 => object(App\Model\Entity\ShootMetum) {

                'new' => true,
                'accessible' => [
                    'shoots_id' => true,
                    'meta_key' => true,
                    'meta_value' => true,
                    'shoot' => true
                ],
                'properties' => [
                    'meta_key' => 'photographer_spaces',
                    'meta_value' => '123'
                ],
                'dirty' => [
                    'meta_key' => true,
                    'meta_value' => true
                ],
                'original' => [],
                'virtual' => [],
                'errors' => [
                    'shoots_id' => [
                        '_required' => 'This field is required'
                    ]
                ],
                'repository' => 'ShootMeta'

            }
        ],
        'created_by' => (int) 1
    ],
    'dirty' => [
        'title' => true,
        'content' => true,
        'datetime' => true,
        'shoot_meta' => true,
        'created_by' => true
    ],
    'original' => [],
    'virtual' => [],
    'errors' => [],
    'repository' => 'Shoots'

}

正如您所看到的,字段shoots_id是必需的,我原本认为它会自动传递下来(尽管此时它还没有执行任何MySQL)。

我觉得我可能以错误的方式解决了这个问题,但是花了整整两天的时间试图做到这一点。其中一天是我试图弄清楚为什么在烘焙后它已经将ShootMeta的很多参考文献命名为ShootMetum,我认为它实际上已经破坏了它。

我遇到的最大问题之一是知道在哪里使用shoot_meta,ShootMeta,shootmeta,shootmetum,ShootMetum等。感觉就像是一个雷区!

/更新

下面保存对象的转储。它显然是在分配它,它似乎没有在SQL中执行它?

'shoot_meta' => [
            (int) 0 => object(App\Model\Entity\ShootMetum) {

                'new' => false,
                'accessible' => [
                    'shoots_id' => true,
                    'meta_key' => true,
                    'meta_value' => true
                ],
                'properties' => [
                    'meta_key' => 'photographer_spaces',
                    'meta_value' => '123',
                    'shoot_id' => '2',
                    'id' => '3'
                ],
                'dirty' => [],
                'original' => [],
                'virtual' => [],
                'errors' => [],
                'repository' => 'ShootMeta'

            },

3 个答案:

答案 0 :(得分:1)

找到它。

当我调试保存时,它指的是shoot_id

'shoot_meta' => [
            (int) 0 => object(App\Model\Entity\ShootMetum) {
                'new' => false,
                'accessible' => [
                    'shoots_id' => true,
                    'meta_key' => true,
                    'meta_value' => true
                ],
                'properties' => [
                    'meta_key' => 'photographer_spaces',
                    'meta_value' => '123',
                    'shoot_id' => '2',
                    'id' => '3'
                ],
                'dirty' => [],
                'original' => [],
                'virtual' => [],
                'errors' => [],
                'repository' => 'ShootMeta'

            },

由于某种原因,它使用了单数名称进行关联。在Shoots.php模型中更改。

$this->hasMany('ShootMeta');

$this->hasMany('ShootMeta',[
    'foreignKey' => 'shoots_id'
]);

答案 1 :(得分:0)

删除shoots_id的验证规则。验证是针对从表单发布的数据,在这种情况下,无法从表单发布foreignKey。您已经在buildRules()方法中设置了规则,以确保在保存之前传递了值,因此删除验证是100%安全的。

答案 2 :(得分:0)

我有同样的问题,现在我的解决方案是将相关数据发送到其他函数/方法并保存。 例如

**

public function add() {
        $kantor = $this->Kantor->newEntity($this->request->data);
        if ($this->request->is('post')) {
            $kantor = $this->Kantor->patchEntity($kantor, $this->request->data);
            $rgndata = $this->request->data['Telpkantor'];
            $this->request->session()->write('rgndata', $rgndata);
            if ($this->Kantor->save($kantor)) {
                $result = $this->Kantor->save($kantor);
                $this->addTelpKantor($rgndata, $result->id);
                $this->Flash->success('The kantor has been saved.');
                return $this->redirect(['action' => 'index']);
            } else {
                $this->Flash->error('The kantor could not be saved. Please, try again.');
            }
        }
        $reffKota = $this->Kantor->ReffKota->find('list', ['limit' => 200]);
        $statusKantor = $this->Kantor->StatusKantor->find('list', ['limit' => 200]);
        $pimpinan = $this->Kantor->Pimpinan->find('list', ['limit' => 200]);
        $jenisTelp = $this->Kantor->Telpkantor->Jenistelp->find('list', ['limit' => 200]);
        $this->set(compact('kantor', 'reffKota', 'statusKantor', 'pimpinan', 'jenisTelp'));
        $this->set('_serialize', ['kantor']);
    }
    public function addTelpKantor($rgndata = null, $kantor_id=null) {
        if (!empty($rgndata[0]['noTelp'])) {
            $this->loadModel('Telpkantor');
            foreach ($rgndata as $rgndata) {
                $rgndata['kantor_id'] =$kantor_id;
                $rgndatasave = $this->Telpkantor->newEntity($rgndata);
                $this->Telpkantor->save($rgndatasave);
            }
        }
    }

**