MjGaiser
MjGaiser

Reputation: 431

Using BelongsToMany association in Cakephp 3

I am trying to associate multiple games to a continuity in my database.

I have 3 tables: continuities, continuities_games and games. The continuities_games table has a continuity_id and a game_id. When I try to select the different games in my selection input, it creates a new game entry in the database and then creates a entry into the join table linking it to that new game entry instead of linking it to the originally selected game.

This is the initialize function in my ContinuitiesTable:

public function initialize(array $config){
    parent::initialize($config);
    $this->belongsToMany('Games');
}

And for my GamesTable:

public function initialize(array $config){
    parent::initialize($config);
    $this->displayField('name');
    $this->addBehavior('Tree');

    //Associations
    $this->hasMany('Children', [
        'className' => 'Games',
        'foreignKey' => 'parent_id',
        'dependant' => true,
        'cascadeCallbacks' => true,
    ]);
    $this->belongsTo('Parent', [
        'className' => 'Games',
    ]);
    $this->hasMany('Books');
    $this->belongsToMany('Continuities');
}

This is my edit function in the ContinuitiesController:

public function edit($id=null){
    $continuity = $this->Continuities->find()->where(['id'=>$id])->contain('Games')->first();
    if ($this->request->is(['post', 'put'])) {
        debug($this->request->data);
        $continuity->start_date = $this->request->data['start_date']['year'].'-'.$this->request->data['start_date']['month'].'-'.$this->request->data['start_date']['day'];
        $continuity->end_date = $this->request->data['end_date']['year'].'-'.$this->request->data['end_date']['month'].'-'.$this->request->data['end_date']['day'];
        //$continuity->start_date = $this->request->data['start_date'];
        //$continuity->end_date = $this->request->data['end_date'];

        $continuity->games = $this->request->data['games'];

        debug($this->Continuities->newEntity($this->request->data)->toArray());
        debug($continuity);
        if ($result = $this->Continuities->save($continuity, ['associated'=>['Games']])) {
            $this->Flash->success(__('The continuity has been updated.'));
            return $this->redirect(['action' => 'view', $continuity->id]);
        }
        $this->Flash->error(__('Unable to update the continuity.'));
    }

    $games = $this->Continuities->Games->getGamesList();
    $this->set(compact('continuity', 'games')); 
}

And finally the edit.ctp form:

<?= $this->Form->create($continuity) ?>
    <fieldset>
        <legend><?= __('Edit Continuity') ?></legend>
        <?= $this->Form->input('start_date') ?>
        <?= $this->Form->input('end_date') ?>
        <?= $this->Form->input('games', ['multiple'=>true]) ?>
   </fieldset>
<?= $this->Form->button(__('Submit')); ?>
<?= $this->Form->end() ?>

Thanks.

Upvotes: 3

Views: 5993

Answers (1)

MjGaiser
MjGaiser

Reputation: 431

There were a few things that needed to be changed to make this work.

First is the Continuities table:

public function initialize(array $config){
    parent::initialize($config);

    $this->belongsToMany('Games', 
        [
            'targetForeignKey' => 'game_id',
            'foreignKey' => 'continuity_id',
            'joinTable' => 'continuities_games',
        ]);
}

Next, the Games table:

public function initialize(array $config){
    parent::initialize($config);

    $this->belongsToMany('Continuities',
        [
            'targetForeignKey' => 'continuity_id',
            'foreignKey' => 'game_id',
            'joinTable' => 'continuities_games',
        ]);
}

Now, the ContinuitiesController edit() function:

public function edit($id=null){
    $continuity = $this->Continuities->find()->where(['id'=>$id])->contain('Games')->first();

    if ($this->request->is(['post', 'put'])) {
        $this->Continuities->patchEntity($continuity, $this->request->data(), ['associated'=>['Games']]);
        if ($result = $this->Continuities->save($continuity, ['associated'=>['Games']])) {
            $this->Flash->success(__('The continuity has been updated.'));
            return $this->redirect(['action' => 'view', $continuity->id]);
        }
        $this->Flash->error(__('Unable to update the continuity.'));
    }

    $games = $this->Continuities->Games->getGamesList();
    $this->set(compact('continuity', 'games')); 
}

And finally, the edit.ctp

<?= $this->Form->create($continuity) ?>
    <fieldset>
        <legend><?= __('Edit Continuity') ?></legend>
        <?= $this->Form->input('start_date') ?>
        <?= $this->Form->input('end_date') ?>
        <?= $this->Form->input('games._ids', ['options' => $games, 'multiple'=>true]) ?>
   </fieldset>
<?= $this->Form->button(__('Submit')); ?>
<?= $this->Form->end() ?>

Upvotes: 6

Related Questions