Если я правильно понимаю ваше экономическое обоснование, вы создаете заявку для клиента и в той же транзакции добавляете в заявку 4 продукта.Итак, вы добавляете билет с 4-мя ассоциированными product_tickets (пунктами в билете).
В модели ProductsTable.php
public function initialize(array $config)
{
parent::initialize($config);
$this->setTable('products');
$this->setDisplayField('id');
$this->setPrimaryKey('id');
$this->addBehavior('Timestamp');
$this->hasMany('ProductTickets', [
'foreignKey' => 'product_id'
]);
}
В модели TicketsTable.php
public function initialize(array $config)
{
parent::initialize($config);
$this->setTable('tickets');
$this->setDisplayField('id');
$this->setPrimaryKey('id');
$this->addBehavior('Timestamp');
$this->hasMany('ProductTickets', [
'foreignKey' => 'ticket_id'
]);
}
В модели ProductTicketsTable.php
public function initialize(array $config)
{
parent::initialize($config);
$this->setTable('product_tickets');
$this->setDisplayField('id');
$this->setPrimaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('Tickets', [
'foreignKey' => 'ticket_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Products', [
'foreignKey' => 'product_id',
'joinType' => 'INNER'
]);
}
Тогда вы можете использовать только контроллер Tickets и сохранять его с соответствующими ProductTickets (позициями в билете).
Итак, в src\Template\Tickets\add.php
, вы можете настроить форму следующим образом:
<?= $this->Form->create($ticket) ?>
<fieldset>
<legend><?= __('Add Ticket') ?></legend>
<?php
echo $this->Form->control('client');
echo $this->Form->control('reference');
?>
</fieldset>
<fieldset>
<legend><?= __('Add Product_Tickets (Ticket items)') ?></legend>
<table>
<thead>
<tr>
<th><?= __('Product') ?></th>
<th><?= __('Qty') ?></th>
<th><?= __('Serial Number') ?></th>
<th><?= __('Notes') ?></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<?php echo $this->Form->control("product_tickets.0.product_id", []) ?>
</td>
<td>
<?php echo $this->Form->control("product_tickets.0.qty", []) ?>
</td>
<td>
<?php echo $this->Form->control("product_tickets.0.serial_number", []) ?>
</td>
<td>
<?php echo $this->Form->control("product_tickets.0.notes", []) ?>
</td>
</tr>
<tr>
<td>
<?php echo $this->Form->control("product_tickets.1.product_id", []) ?>
</td>
<td>
<?php echo $this->Form->control("product_tickets.1.qty", []) ?>
</td>
<td>
<?php echo $this->Form->control("product_tickets.1.serial_number", []) ?>
</td>
<td>
<?php echo $this->Form->control("product_tickets.1.notes", []) ?>
</td>
</tr>
<tr>
<td>
<?php echo $this->Form->control("product_tickets.2.product_id", []) ?>
</td>
<td>
<?php echo $this->Form->control("product_tickets.2.qty", []) ?>
</td>
<td>
<?php echo $this->Form->control("product_tickets.2.serial_number", []) ?>
</td>
<td>
<?php echo $this->Form->control("product_tickets.2.notes", []) ?>
</td>
</tr>
<tr>
<td>
<?php echo $this->Form->control("product_tickets.3.product_id", []) ?>
</td>
<td>
<?php echo $this->Form->control("product_tickets.3.qty", []) ?>
</td>
<td>
<?php echo $this->Form->control("product_tickets.3.serial_number", []) ?>
</td>
<td>
<?php echo $this->Form->control("product_tickets.3.notes", []) ?>
</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
* ( Обратите внимание, есть другие / лучшие способы создания форм с несколькими связанными записями.)
В контроллере Tickets в методе add:
public function add()
{
$ticket = $this->Tickets->newEntity();
if ($this->request->is('post')) {
$data = $this->request->getData();
$ticket = $this->Tickets->newEntity($data, [
'associated' => ['ProductTickets']
]);
$ticket = $this->Tickets->patchEntity($ticket, $this->request->getData(),['associated' => 'ProductTickets'
]);
if ($this->Tickets->save($ticket)) {
$this->Flash->success(__('The ticket has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The ticket could not be saved. Please, try again.'));
}
$products = $this->Tickets->ProductTickets->Products->find('list');
$this->set(compact('ticket', 'products'));
}
Это работает для меня и должно сохранить любую комбинацию product_ids, связанную с ticket_id.Например, данные этого запроса сохраняются, как и ожидалось:
debug($this->request->getData());
[
'client' => '1',
'reference' => 'reference 1',
'product_tickets' => [
(int) 0 => [
'product_id' => '1',
'qty' => '12',
'serial_number' => 'abc1234',
'notes' => 'note1'
],
(int) 1 => [
'product_id' => '2',
'qty' => '5',
'serial_number' => '4321cba',
'notes' => 'note2'
],
(int) 2 => [
'product_id' => '1',
'qty' => '6',
'serial_number' => 'a4b3c21',
'notes' => 'note3'
],
(int) 3 => [
'product_id' => '3',
'qty' => '21',
'serial_number' => '4c3b2a1',
'notes' => 'note4'
]
]
]
Согласно инструкции, Сохранение имеет много ассоциаций
Важное примечание, если какой-либо из 4 продуктов, которые вы планируетесохранить на тикете NULL, тогда вам нужно удалить этот продукт из данных запроса.Вы можете сделать это с помощью метода beforeMarshal в модели ProductTicketsTable.
Надеюсь, это то, что вы имели в виду и полезно.
Cheers,
D.