Cake PHP 3 патч сущности создает новые связанные сущности - PullRequest
0 голосов
/ 23 марта 2020

Я пытаюсь обновить сущность ClientContactName , используя функцию patchEntity(), которая имеет ассоциацию ClientContactAddresses . ClientContactName сущность обновляется, как и следовало ожидать. Однако, хотя ClientContactAddress является существующим объектом, функция patchEntity() создает объект new ClientContactAddress и добавляет его в таблицу при сохранении.

Если я включу скрытое поле 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.-->

Перед исправлением соответствующие части сущности, как я и ожидал, ie [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.
    ]
],

И после исправления создается новая сущность, ie [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'

        }],
     //..//

1 Ответ

0 голосов
/ 23 марта 2020

Вам не нужно делать поле id доступным, на самом деле вам не следует этого делать, поскольку это может быть потенциальной угрозой безопасности.

Все, что вам нужно сделать, - это передать Идентификатор записи в данных. Маршаллеру нужно это значение, чтобы можно было выяснить, какую существующую сущность нужно соединить с остальными данными.

Использование скрытого поля для передачи идентификатора абсолютно нормально. Помощник формы автоматически выберет скрытое поле при создании элемента управления для столбца первичного ключа.

См. Также

...