# Why belongsToMany association is not saved to joinTable?

**URL:** <https://discourse.cakephp.org/t/why-belongstomany-association-is-not-saved-to-jointable/5594>\
**Category:** Need Help\
**Created:** [January 31, 2019, 10:05am UTC](https://discourse.cakephp.org/t/why-belongstomany-association-is-not-saved-to-jointable/5594 "2019-01-31T10:05:05Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![ivnku](https://avatars.discourse-cdn.com/v4/letter/i/b77776/32.png) [@ivnku](https://discourse.cakephp.org/u/ivnku)\
**Post date:** [January 31, 2019, 10:05am UTC](https://discourse.cakephp.org/t/why-belongstomany-association-is-not-saved-to-jointable/5594/1 "2019-01-31T10:05:05Z")

</div>

I am new to php frameworks and I’ve started to learn cakephp few days ago, but even after reading cakephp cookbook about saving belongsToMany associations I still don’t know how to implement it in my situation.

I have three tables:  
**clients:**  
id | firstname | lastname | phone | email  
**interests:**  
id | text | comment | status\_id | created\_at  
**clients\_interests:**  
client\_id | interest\_id

Models and entities were baked so I don’t think it’s something wrong there, but here is the code: **ClientsTable.php**

```auto
class ClientsTable extends Table
{            
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->setTable('clients');
        $this->setDisplayField('id');
        $this->setPrimaryKey('id');

        $this->belongsToMany('Interests', [
            'foreignKey' => 'client_id',
            'targetForeignKey' => 'interest_id',
            'joinTable' => 'clients_interests'
        ]);
    }

    public function validationDefault(Validator $validator)
    {
        $validator
            ->integer('id')
            ->allowEmptyString('id', 'create');

        $validator
            ->scalar('firstname')
            ->maxLength('firstname', 64)
            ->requirePresence('firstname', 'create')
            ->allowEmptyString('firstname', false);

        $validator
            ->scalar('middlename')
            ->maxLength('middlename', 64)
            ->allowEmptyString('middlename');

        $validator
            ->scalar('lastname')
            ->maxLength('lastname', 64)
            ->requirePresence('lastname', 'create')
            ->allowEmptyString('lastname', false);

        $validator
            ->scalar('phone')
            ->maxLength('phone', 24)
            ->requirePresence('phone', 'create')
            ->allowEmptyString('phone', false)
            ->add('phone', 'unique', ['rule' => 'validateUnique', 'provider' => 'table']);

        $validator
            ->email('email')
            ->allowEmptyString('email');

        return $validator;
    }

    public function buildRules(RulesChecker $rules)
    {
        $rules->add($rules->isUnique(['email']));
        $rules->add($rules->isUnique(['phone']));

        return $rules;
    }
}

```

**InterestsTable.php**

```auto
class InterestsTable extends Table
{
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->setTable('interests');
        $this->setDisplayField('id');
        $this->setPrimaryKey('id');

        $this->belongsTo('Statuses', [
            'foreignKey' => 'status_id',
            'joinType' => 'INNER'
        ]);
        $this->belongsToMany('Clients', [
            'foreignKey' => 'interest_id',
            'targetForeignKey' => 'client_id',
            'joinTable' => 'clients_interests'
        ]);
    }

    public function validationDefault(Validator $validator)
    {
        $validator
            ->integer('id')
            ->allowEmptyString('id', 'create');

        $validator
            ->scalar('text')
            ->maxLength('text', 128)
            ->requirePresence('text', 'create')
            ->allowEmptyString('text', false);

        $validator
            ->scalar('comment')
            ->maxLength('comment', 128)
            ->allowEmptyString('comment');

        $validator
            ->date('created_at')
            ->requirePresence('created_at', 'create')
            ->allowEmptyDate('created_at', false);

        return $validator;
    }

    public function buildRules(RulesChecker $rules)
    {
        $rules->add($rules->existsIn(['status_id'], 'Statuses'));

        return $rules;
    }

    public function getAll($id)
    {
        $connection = ConnectionManager::get('default');
        $results = $connection
            ->execute('SELECT i.*, s.name status_name, s.classname status_classname FROM interests i INNER JOIN clients_interests ci ON ci.interest_id=i.id AND ci.client_id=:client_id INNER JOIN statuses s ON i.status_id=s.id ORDER BY created_at DESC;', ['client_id' => $id])
            ->fetchAll('assoc');
        return $results;
    }
}

```

**ClientsInterestsTable.php**

```auto
class ClientsInterestsTable extends Table
{            
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->setTable('clients_interests');
        $this->setDisplayField('client_id');
        $this->setPrimaryKey(['client_id', 'interest_id']);

        $this->belongsTo('Clients', [
            'foreignKey' => 'client_id',
            'joinType' => 'INNER'
        ]);
        $this->belongsTo('Interests', [
            'foreignKey' => 'interest_id',
            'joinType' => 'INNER'
        ]);
    }

    public function buildRules(RulesChecker $rules)
    {
        $rules->add($rules->existsIn(['client_id'], 'Clients'));
        $rules->add($rules->existsIn(['interest_id'], 'Interests'));

        return $rules;
    }
}

```

Client entity - **Client.php**

```auto
class Client extends Entity
{         
    protected $_accessible = [
        'firstname' => true,
        'middlename' => true,
        'lastname' => true,
        'phone' => true,
        'email' => true
    ];
}

```

Interest entity - **Interest.php**

```auto
class Interest extends Entity
{          
    protected $_accessible = [
        'text' => true,
        'comment' => true,
        'status_id' => true,
        'created_at' => true,
        'clients_interest' => true,
        'status' => true
    ];
}

```

ClientsInterests entity - **ClientsInterests.php**

```auto
class ClientsInterest extends Entity
{

    protected $_accessible = [
        'client' => true,
        'interest' => true
    ];
}

```

And then in my controller I get all the data from a form. Interest entity after patchEntity() gets all its data besides client\_id data for joinTable. And after save method new interest in **interests** table is created but there is no new row in **clients\_interests** table. I’ve tried a lot of things from stackoverflow but it didn’t work because I can’t understand the mechanism of saving associated data even after reading the manual. Could anyone explain me in simple words how to save belongsToMany associated data? Here is the code of my save method in **InterestsController.php:**

```auto
public function add()
    {
        $this->request->allowMethod(['ajax', 'post']);
        $this->response->withDisabledCache();

        $interest = $this->Interests->newEntity();
        $interest = $this->Interests->patchEntity($interest, $this->request->getData(), 
            ['associated'=>['Clients._joinData']]
        );       

        if($this->Interests->save($interest)) {
            $result = ['error' => null, 'error_text' => 'SUCCESSFUL'];
        } else {
            $result = ['error' => null, 'error_text' => 'ERRORS ERRORS ERRORS'];
        }

        $result = ['error' => null, 'error_text' => 'ERRORS ERRORS ERRORS'];
        $this->set('result', $result);
        $this->set('_serialize', ['result']);
    }

```

And in my template I use this input for getting client\_id:

```auto
<?php echo $this->Form->control('clients.0.client_id', ['hidden', 'type'=>'text','id'=>'client-id', 'class'=>'form-control']); ?>

```

Request data looks like this: [https://i.stack.imgur.com/uQ1Rt.png](https://i.stack.imgur.com/uQ1Rt.png)  
And Interest entity after patchEntity() looks like this: [https://i.stack.imgur.com/iohL0.png](https://i.stack.imgur.com/iohL0.png)

Also I wonder, what ‘clients\_interest’ and ‘status’ fields were baked for? Is it wrong?
