Add a new Entity with associated Table with joinData

I have 3 Tables:

  • ingredients (id, name)
  • dishsizes (id, name)
  • dishsizes_ingredients (id, dishsize_id, ingredient_id, unitprice)

I want to add a new Ingredient and define in the same form the unitprices.

in the add-form I have:

<?php foreach ($dishsizes as $i => $dishsize): ?>
<div class="flex flex-col w-full">
  <label class="text-black"><?= $dishsize->name?></label>
  <?= $this->Form->number('dishsizes.'.$i.'._joinData.unitprice',['min'=>1,'step'=>0.01,'class'=>'w-2/3 mt-2 mb-6 px-4 py-2 border rounded-lg text-lg text-gray-700 focus:outline-none','label'=>'none','hiddenField'=>false,'default'=>NULL])?>
  <?= $this->Form->hidden('dishsizes.'.$i.'._joinData.currency_id',['value'=>1])?>
  <?= $this->Form->hidden('dishsizes.'.$i.'._joinData.dishsize_id',['value'=>$dishsize->id])?>
<?php endforeach; ?>

This results in post data:

‘dishsizes’ => [
(int) 0 => [
‘_joinData’ => [
‘unitprice’ => ‘5’, ‘currency_id’ => ‘1’, ‘dishsize_id’ => ‘1’,
], (int) 1 => [ ], (int) 2 => [ ], (int) 3 => [ ],

So far so good, but the ingredient entity, created with
$ingredient = $this->Ingredients->patchEntity($ingredient, $this->request->getData(),['associated'=>['Foodadditives','Ingredientnotes','Dishsizes._joinData']]);

has errors in dishsizes.

'dishsizes' => [
(int) 0 => object(App\Model\Entity\Dishsize) id:13 {
'_joinData' => object(App\Model\Entity\DishsizesIngredient) id:14 { } '[new]' => true '[accessible]' => [ ] '[dirty]' => [ ] '[original]' => [ ] '[virtual]' => [ ] '[hasErrors]' => true '[errors]' => [
'name' => [
'_required' => 'This field is required',

I think the ingredient id is missing in the dishsizes part of the ingredient id.
But how to solve this?

If I’m reading this correctly, what it’s complaining about is that the name field in the DishsizesIngredient entity is blank.

yes, that is right.
The Controller does not know, that the dishsize already exists.
I made a little workaround and save the data for dishsizes_ingredients separately, but maybe there is a better solution?

Does dishsizes_ingredients even have a name column in it? Why is the validation looking for that?

dishsizes_ingredients does not have a name column.

but I have seen, that a similar question already was discussed here: Save tags to articles (belongsToMany) with joinData - #12 by TheMiller

And the answer is: it does not work out of the box:-)
Thanks for your help

Finally found a solution.
I added

echo $this->Form->hidden(‘dishsizes.’.$i.’.id’, [‘value’ => $dishsize->id]);

to the input field, so that it now looks like:

<?php foreach ($dishsizes as $i => $dishsize): ?>
    <div class="flex flex-col w-full">
      <label class="text-black"><?= $dishsize->name?></label>
          echo $this->Form->hidden('dishsizes.'.$i.'.id', ['value' => $dishsize->id]);
          echo $this->Form->number('dishsizes.'.$i.'._joinData.unitprice',['min'=>1,'step'=>0.01,'class'=>'w-2/3 mt-2 mb-6 px-4 py-2 border rounded-lg text-lg text-gray-700 focus:outline-none','label'=>'none','hiddenField'=>false,'default'=>NULL]);
          echo $this->Form->hidden('dishsizes.'.$i.'._joinData.currency_id',['value'=>1]);
          echo $this->Form->hidden('dishsizes.'.$i.'._joinData.dishsize_id',['value'=>$dishsize->id]);
  <?php endforeach; ?>

Maybe it is helpful for someone