CakePHP 3 补丁实体创建新的关联实体
CakePHP 3 patch entity creates new associated entities
我正在尝试使用 patchEntity()
函数更新 ClientContactName 实体,该函数具有 ClientContactAddresses 关联。 ClientContactName 实体如我所料更新。但是,即使 ClientContactAddress 是一个现有实体,patchEntity()
函数也会创建一个 new ClientContactAddress 实体,并在保存时将其添加到 table。
如果我在视图中包含隐藏的 id
字段并将 id
添加为关联数组中的 accessibleField
,它确实会更新现有的 ClientContactAddress,但我很难想象这是处理事情的正确方法。
我的问题是:如何编写修补函数代码以便更新现有关联而不是创建新关联?
关系是 ClientContactName hasMany
ClientContactAddresses。下面是我的代码,没有隐藏 id
字段和 accessibleField
调整。
我在控制器中的 edit()
函数如下所示:
public function edit($id = null)
{
$clientContactName = $this->ClientContactNames->get($id, [
'contain' => [
'Clients',
'ClientContactAddresses'
]
]);
if ($this->getRequest()->is(['patch', 'post', 'put'])) {
$data = $this->getRequest()->getData();
$clientContactName = $this->ClientContactNames->patchEntity(
$clientContactName,
$data, [
'associated' => ['ClientContactAddresses']
]
);
if ($this->ClientContactNames->save($clientContactName)) {
$this->Flash->success(__('The client contact has been saved.'));
return $this->redirect(['controller' => 'Clients', 'action' => 'view', $clientContactName->client->id]);
}
$this->Flash->error(__('The client contact could not be saved. Please, try again.'));
}
$this->set(compact('clientContactName'));
}
视图如下所示:
<div class="container-fluid clearfix col-lg-10">
<?= $this->Form->create($clientContactName) ?>
<fieldset>
<!--bits that matter-->
<div class="row stack-row">
<div class="col-6">
<?= $this->Form->control('first_name') ?>
</div>
<div class="col-6">
<?= $this->Form->control('last_name') ?>
</div>
</div>
<?= $this->element('address_form', ['showTopper' => true, 'entity' => 'client_contact_addresses.0']) ?>
</fieldset>
<?= $this->Form->button(__('Submit'), ['class' => 'btn btn-primary']) ?>
<?= $this->Form->end() ?>
</div>
这是元素:
<?php
$prefix = ((empty($entity)) ? '' : $entity . '.');
if (!empty($showTopper)):
?>
<div class="row stack-row">
<div class="col">
<legend class="sub-topper"><?= __('Address') ?></legend>
</div>
</div>
<?php endif; ?>
<div class="row stack-row">
<div class="col-lg-6">
<?php
echo $this->Form->control($prefix . 'address_1');
echo $this->Form->control($prefix . 'address_2');
echo $this->Form->control($prefix . 'address_3');
?>
</div>
</div>
<!--etc.-->
在修补之前,实体的相关部分如我所料,即 [new]
设置为 false
:
object(App\Model\Entity\ClientContactName) {
'id' => (int) 1,
'first_name' => 'xxxx',
'last_name' => 'xxxx',
'client_id' => (int) 19,
'client_contact_addresses' => [
(int) 0 => object(App\Model\Entity\ClientContactAddress) {
'id' => (int) 12,
'address_1' => 'xxxx',
'address_2' => 'xxxx',
'address_3' => 'xxxx',
etc...
'client_contact_name_id' => (int) 1,
'[new]' => false,
'[accessible]' => [
'address_1' => true,
'address_2' => true,
'address_3' => true,
etc.
'client' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'ClientContactAddresses'
}],
//..//
请求数据显示地址字段值。虽然因为我没有隐藏的 id
字段,所以不会出现 id
值:
'first_name' => 'xxxx',
'last_name' => 'xxxx',
'client_contact_addresses' => [
(int) 0 => [
'address_1' => 'xxxx',
'address_2' => 'xxxx',
'address_3' => 'xxxx',
etc.
]
],
并且在打补丁之后,创建了新实体,即[new]
设置为true
:
object(App\Model\Entity\ClientContactName) {
'id' => (int) 1,
'first_name' => 'xxxx',
'last_name' => 'xxxx',
'client_id' => (int) 19,
'client_contact_addresses' => [
(int) 0 => object(App\Model\Entity\ClientContactAddress) {
'address_1' => 'xxxx',
'address_2' => 'xxxx',
'address_3' => 'xxxx',
etc.
'[new]' => true,
'[accessible]' => [
'address_1' => true,
'address_2' => true,
'address_3' => true,
etc.
'id' => true
],
'[dirty]' => [
'address_1' => true,
'address_2' => true,
'address_3' => true,
etc.
],
'[original]' => [],
'[virtual]' => [],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'ClientContactAddresses'
}],
//..//
您不需要使 id
字段可访问,事实上您真的不应该这样做,因为它可能存在安全风险。
您需要做的就是在数据中传递记录的ID。编组器需要该值以便能够找出要用其余数据修补的现有实体。
使用隐藏字段传递 ID 绝对没问题。表单助手在为主键列生成控件时会自动选择一个隐藏字段。
另见
我正在尝试使用 patchEntity()
函数更新 ClientContactName 实体,该函数具有 ClientContactAddresses 关联。 ClientContactName 实体如我所料更新。但是,即使 ClientContactAddress 是一个现有实体,patchEntity()
函数也会创建一个 new ClientContactAddress 实体,并在保存时将其添加到 table。
如果我在视图中包含隐藏的 id
字段并将 id
添加为关联数组中的 accessibleField
,它确实会更新现有的 ClientContactAddress,但我很难想象这是处理事情的正确方法。
我的问题是:如何编写修补函数代码以便更新现有关联而不是创建新关联?
关系是 ClientContactName hasMany
ClientContactAddresses。下面是我的代码,没有隐藏 id
字段和 accessibleField
调整。
我在控制器中的 edit()
函数如下所示:
public function edit($id = null)
{
$clientContactName = $this->ClientContactNames->get($id, [
'contain' => [
'Clients',
'ClientContactAddresses'
]
]);
if ($this->getRequest()->is(['patch', 'post', 'put'])) {
$data = $this->getRequest()->getData();
$clientContactName = $this->ClientContactNames->patchEntity(
$clientContactName,
$data, [
'associated' => ['ClientContactAddresses']
]
);
if ($this->ClientContactNames->save($clientContactName)) {
$this->Flash->success(__('The client contact has been saved.'));
return $this->redirect(['controller' => 'Clients', 'action' => 'view', $clientContactName->client->id]);
}
$this->Flash->error(__('The client contact could not be saved. Please, try again.'));
}
$this->set(compact('clientContactName'));
}
视图如下所示:
<div class="container-fluid clearfix col-lg-10">
<?= $this->Form->create($clientContactName) ?>
<fieldset>
<!--bits that matter-->
<div class="row stack-row">
<div class="col-6">
<?= $this->Form->control('first_name') ?>
</div>
<div class="col-6">
<?= $this->Form->control('last_name') ?>
</div>
</div>
<?= $this->element('address_form', ['showTopper' => true, 'entity' => 'client_contact_addresses.0']) ?>
</fieldset>
<?= $this->Form->button(__('Submit'), ['class' => 'btn btn-primary']) ?>
<?= $this->Form->end() ?>
</div>
这是元素:
<?php
$prefix = ((empty($entity)) ? '' : $entity . '.');
if (!empty($showTopper)):
?>
<div class="row stack-row">
<div class="col">
<legend class="sub-topper"><?= __('Address') ?></legend>
</div>
</div>
<?php endif; ?>
<div class="row stack-row">
<div class="col-lg-6">
<?php
echo $this->Form->control($prefix . 'address_1');
echo $this->Form->control($prefix . 'address_2');
echo $this->Form->control($prefix . 'address_3');
?>
</div>
</div>
<!--etc.-->
在修补之前,实体的相关部分如我所料,即 [new]
设置为 false
:
object(App\Model\Entity\ClientContactName) {
'id' => (int) 1,
'first_name' => 'xxxx',
'last_name' => 'xxxx',
'client_id' => (int) 19,
'client_contact_addresses' => [
(int) 0 => object(App\Model\Entity\ClientContactAddress) {
'id' => (int) 12,
'address_1' => 'xxxx',
'address_2' => 'xxxx',
'address_3' => 'xxxx',
etc...
'client_contact_name_id' => (int) 1,
'[new]' => false,
'[accessible]' => [
'address_1' => true,
'address_2' => true,
'address_3' => true,
etc.
'client' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'ClientContactAddresses'
}],
//..//
请求数据显示地址字段值。虽然因为我没有隐藏的 id
字段,所以不会出现 id
值:
'first_name' => 'xxxx',
'last_name' => 'xxxx',
'client_contact_addresses' => [
(int) 0 => [
'address_1' => 'xxxx',
'address_2' => 'xxxx',
'address_3' => 'xxxx',
etc.
]
],
并且在打补丁之后,创建了新实体,即[new]
设置为true
:
object(App\Model\Entity\ClientContactName) {
'id' => (int) 1,
'first_name' => 'xxxx',
'last_name' => 'xxxx',
'client_id' => (int) 19,
'client_contact_addresses' => [
(int) 0 => object(App\Model\Entity\ClientContactAddress) {
'address_1' => 'xxxx',
'address_2' => 'xxxx',
'address_3' => 'xxxx',
etc.
'[new]' => true,
'[accessible]' => [
'address_1' => true,
'address_2' => true,
'address_3' => true,
etc.
'id' => true
],
'[dirty]' => [
'address_1' => true,
'address_2' => true,
'address_3' => true,
etc.
],
'[original]' => [],
'[virtual]' => [],
'[hasErrors]' => false,
'[errors]' => [],
'[invalid]' => [],
'[repository]' => 'ClientContactAddresses'
}],
//..//
您不需要使 id
字段可访问,事实上您真的不应该这样做,因为它可能存在安全风险。
您需要做的就是在数据中传递记录的ID。编组器需要该值以便能够找出要用其余数据修补的现有实体。
使用隐藏字段传递 ID 绝对没问题。表单助手在为主键列生成控件时会自动选择一个隐藏字段。
另见