CakePHP 3 保存 BelongsToMany 关联未知类型“”错误
Posted
技术标签:
【中文标题】CakePHP 3 保存 BelongsToMany 关联未知类型“”错误【英文标题】:CakePHP 3 Saving BelongsToMany Association Unknown type "" Error 【发布时间】:2015-08-14 20:14:38 【问题描述】:我一直在拼命想弄清楚为什么我的电子邮件(belongsToMany Guest (belongsToMany Emails))无法保存。当我尝试使用关联数据(来宾)保存电子邮件模型时,它在 $this->Emails->save($email) 处失败:
未知类型“”错误 无效参数异常
此时我已经按照 CakeBookmarks 示例 (http://book.cakephp.org/3.0/en/tutorials-and-examples/bookmarks/intro.html) 进行了关系和编辑表单。甚至构建它并从中提取代码。
这是我项目中的相关代码,感谢任何帮助或推测:
为 emails_guests 连接表创建语句:
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::初始化
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::初始化
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'
]);
电子邮件创建/更新视图 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() ?>
最后是处理相关保存的控制器:
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']);
我保存电子邮件并选择一位或多位客人时的请求数据(触发无效类型“”错误):
[
'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'
]
堆栈跟踪:
⟩ 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
根据文档和示例,它应该可以正常工作。提前致谢!
【问题讨论】:
错误几乎总是附带堆栈跟踪和上下文信息(如果没有,请检查日志),请始终将它们都包含在您的问题中! 知道了。编辑问题以包含堆栈跟踪。 【参考方案1】:看起来读取/缓存的架构有问题,或者您为连接表类定义了不正确的主键。使用像您在此处显示的那样的复合主键,它永远不会到达代码中引发该异常的点。
删除tmp/cache/models/
,如果你有一个EmailsGuestsTable
类,通过Table::primaryKey()
检查它是否以及它设置了什么,如果使用,它应该是
['email_id', 'guest_id']
也许您的表最初具有不同的主键,而您后来对其进行了更改而没有清除缓存和/或更新相应的表类。
【讨论】:
这很有帮助。谢谢你。我已经尝试删除缓存,但问题出在我的 EmailsGuestsTable 中。需要删除这些行并删除缓存: // $this->displayField('id'); // $this->primaryKey('id'); 刚刚在 Cakephp3 中发现了同样的问题,你的评论救了我,谢谢。以上是关于CakePHP 3 保存 BelongsToMany 关联未知类型“”错误的主要内容,如果未能解决你的问题,请参考以下文章
在 CakePHP 3 中保存 belongsToMany 关联