CakePHP 3 Saving BelongsToMany Association Unknown Type Error Error

I banged my head against the wall, trying to understand why my emails (owned by Guests (owned by many emails)) would not be saved. When I try to save the email model with the associated data (guests), it fails in $ this-> Emails-> save ($ email) with:

Unknown type "" Error InvalidArgumentException

I followed the CakeBookmarks example ( http://book.cakephp.org/3.0/en/tutorials-and-examples/bookmarks/intro.html ) to tee at this point for relationships and form editing. And even built it and pulled the code from it.

Here is the relevant code from my project, any help or speculation is evaluated:

Create an operator for the emails_guests connection table:

CREATE TABLE emails_guests ( email_id INT NOT NULL, guest_id INT NOT NULL, PRIMARY KEY (email_id, guest_id), FOREIGN KEY guest_key(guest_id) REFERENCES guests(id), FOREIGN KEY email_key(email_id) REFERENCES emails(id) ); 

EmailsTable :: initialize

 public function initialize(array $config) { // parent::initialize($config); $this->table('emails'); $this->displayField('title'); $this->primaryKey('id'); $this->addBehavior('Timestamp'); $this->belongsToMany('Guests', [ 'foreignKey' => 'email_id', 'targetForeignKey' => 'guest_id', 'joinTable' => 'emails_guests' ]); } 

GuestsTable :: initialize

 public function initialize(array $config){ parent::initialize($config); $this->table('guests'); $this->displayField('name'); $this->primaryKey('id'); $this->addBehavior('Timestamp'); $this->belongsTo('Invitations', [ 'foreignKey' => 'invitation_id' ]); $this->hasMany('Messages', [ 'foreignKey' => 'guest_id' ]); $this->belongsTo('SeatingGroups', [ 'foreignKey' => 'seating_group_id' ]); $this->belongsToMany('Emails', [ 'foreignKey' => 'guest_id', 'targetForeignKey' => 'email_id', 'joinTable' => 'emails_guests' ]); } 

Create / update email manage.ctp

  <?= $this->Form->create($email); ?> <div class="row"> <div class="col-sm-12"> <?= $this->Form->input('title', ['id' => false]); ?> </div> </div> <div class="row"> <div class="col-sm-12"> <?= $this->Form->input('subject'); ?> </div> </div> <div class="row"> <div class="col-sm-12"> <?= $this->Form->input('message', ['class'=>'email-body']); ?> </div> </div> <div class="row"> <div class="col-sm-6"> <?= $this->Form->input( 'guests._ids', [ // 'type' => 'select', 'options' => $guests, // 'multiple' => true, // 'empty' => 'Please select the recipients.', // 'label'=>'Recipients' ] ); ?> </div> <div class="col-sm-6"> <div class="row"> <div class="col-sm-12"> <?= $this->Form->input('send_by', ['id' => 'send-by', 'type' => 'text']); ?> </div> </div> <div class="row"> <div class="col-sm-6"> <?= $this->Form->checkbox('now'); ?> <label for="now">Send Now</label> </div> <div class="col-sm-6"> <?= $this->Form->input( __('Save'), [ 'type' => 'submit', 'class' => 'inline', 'label' => false ] ) ?> </div> </div> </div> </div> <div class="row"> <div class="col-sm-12"> </div> </div> <div class="clearfix"></div> <?= $this->Form->end() ?> 

And finally, the controller processes the specified save:

 public function manage($id = null) { $this->set('title', 'Manage Emails'); if(isset($id)) { $email = $this->Emails->get($id, [ 'contain' => ['Guests'] ]); $this->set('title', 'Email: ' . $email->title); } else { $email = $this->Emails->newEntity(); $this->set('title', 'Create Email'); } if ($this->request->is(['patch', 'post', 'put'])) { debug($email); $email = $this->Emails->patchEntity($email, $this->request->data); debug($email); debug($this->request->data); if ($this->Emails->save($email)) { if($email->now == true) { $this->process($email->id, $id); } $this->Flash->success('The email has been saved.'); return $this->redirect(['action' => 'manage', $email->id]); } else { $this->Flash->error('The email could not be saved. Please, try again.'); } } $guests = $this->Emails->Guests->find('list')->select(['id', 'first_name', 'last_name', 'email'])->toArray(); $this->set('email', $email); $this->set('guests', $guests); $emails = $this->Emails->find(); $this->set('emails', $this->paginate($emails)); $this->set('_serialize', ['emails']); } 

Request data when I save an email and select one or more guests (which causes an invalid type error):

 [ 'title' => 'Test Email Edit', 'subject' => 'Hi! {{guest.first_name}}, we're testing some new features!2', 'message' => 'Hi {{guest.first_name}} {{guest.last_name}}, We're testing some new features with recursive data. Let me tell you a bit about you: Your seating group is: {{guest.seating_group.name}}. Your invitation is: {{guest.invitation.name}} Which we sent to: {{guest.invitation.address}} Thanks! Hope this comes out okay... ', 'guests' => [ '_ids' => [ (int) 0 => '1' ] ], 'send_by' => '', 'now' => '0' ] 

Stack trace:

 ⟩ Cake\Database\Type::build CORE/src/ORM/Table.php, line 1552 ⟩ Cake\ORM\Table->_newId CORE/src/ORM/Table.php, line 1489 ⟩ Cake\ORM\Table->_insert CORE/src/ORM/Table.php, line 1436 ⟩ Cake\ORM\Table->_processSave CORE/src/ORM/Table.php, line 1367 ⟩ Cake\ORM\Table->Cake\ORM\{closure} CORE/src/Database/Connection.php, line 561 ⟩ Cake\Database\Connection->transactional CORE/src/ORM/Table.php, line 1368 ⟩ Cake\ORM\Table->save CORE/src/ORM/Association/BelongsToMany.php, line 557 ⟩ Cake\ORM\Association\BelongsToMany->_saveLinks CORE/src/ORM/Association/BelongsToMany.php, line 506 ⟩ Cake\ORM\Association\BelongsToMany->_saveTarget CORE/src/ORM/Association/BelongsToMany.php, line 750 ⟩ Cake\ORM\Association\BelongsToMany->Cake\ORM\Association\{closure} CORE/src/Database/Connection.php, line 561 ⟩ Cake\Database\Connection->transactional CORE/src/ORM/Association/BelongsToMany.php, line 769 ⟩ Cake\ORM\Association\BelongsToMany->replaceLinks CORE/src/ORM/Association/BelongsToMany.php, line 445 ⟩ Cake\ORM\Association\BelongsToMany->saveAssociated CORE/src/ORM/AssociationCollection.php, line 254 ⟩ Cake\ORM\AssociationCollection->_save CORE/src/ORM/AssociationCollection.php, line 230 ⟩ Cake\ORM\AssociationCollection->_saveAssociations CORE/src/ORM/AssociationCollection.php, line 195 ⟩ Cake\ORM\AssociationCollection->saveChildren CORE/src/ORM/Table.php, line 1447 ⟩ Cake\ORM\Table->_processSave CORE/src/ORM/Table.php, line 1367 ⟩ Cake\ORM\Table->Cake\ORM\{closure} CORE/src/Database/Connection.php, line 561 ⟩ Cake\Database\Connection->transactional CORE/src/ORM/Table.php, line 1368 ⟩ Cake\ORM\Table->save APP/Controller/EmailsController.php, line 61 ⟩ App\Controller\EmailsController->manage [internal function] ⟩ call_user_func_array CORE/src/Controller/Controller.php, line 411 ⟩ Cake\Controller\Controller->invokeAction CORE/src/Routing/Dispatcher.php, line 114 ⟩ Cake\Routing\Dispatcher->_invoke CORE/src/Routing/Dispatcher.php, line 87 ⟩ Cake\Routing\Dispatcher->dispatch ROOT/webroot/index.php, line 37 

It should work fine in accordance with documents and examples. Thanks in advance!

+4
source share
1 answer

It looks like something is wrong with the read / cache scheme, or you are defining the wrong primary key for the connection table class. With a compound primary key similar to the one you show here, it should never go to the point in the code where this excpetion is selected.

Delete tmp/cache/models/ , and if you have the EmailsGuestsTable class, check that it installs via Table::primaryKey() , if used, it should be

 ['email_id', 'guest_id'] 

Perhaps your table originally had a different primary key, and you subsequently made changes to it without clearing the cache and / or updating the corresponding table class.

+2
source

All Articles