Save various records in belongstomany association in cakephp 4.4

I have two tables with a belongstomany association (Profiles and SourcingEvents, join table SourcingEventsProfiles), the primary key for SourcingEventsProfiles is sourcing_event_id, profile_id and main_gate, I want to save one record to SourcingEvents and various records to SourcingEventsProfiles and no records in Profiles, for that I use a table named ProfilesGates that is not related to the other tables, the problem is that in ProfilesGates I have records where profile_id is repeated because there are some profiles that have two main_gate (A or B), how can I solve this issue?
This is the code for add action:

    public function add()
    {
		$this->loadModel("ProfilesGates");
        $sourcingEvent = $this->SourcingEvents->newEmptyEntity();
		if ($this->request->is('post')) {
            $sourcingEvent = $this->SourcingEvents->newEntity($this->request->getData(), [
				'associated' => [
					'Profiles._joinData' => [
						'accessibleFields' => ['sourcing_event_id' => true, 'profile_id' => true, 'main_gate' => true],
					]
				]
			]);
			if(!empty($sourcingEvent->profiles)) {
				$joinData = [];
				foreach($sourcingEvent->profiles as $key => $data){
					if(!empty($data->_joinData->profile_id)){
						$profile_id = $data->_joinData->profile_id;
						$main_gate = $data->_joinData->main_gate;
						$joinData[$key] = new Entity(['profile_id' => $profile_id, 'main_gate' => $main_gate], ['markNew' => true]);
					}
				}
				$sourcingEvent->_joinData = $joinData;
			}
			debug($sourcingEvent);
			if ($this->SourcingEvents->save($sourcingEvent, ['associated' => 'SourcingEventsProfiles'])) {
				$this->Flash->success(__('El evento ha sido creado'));
				return $this->redirect(array('action' => 'index'));
			}
			$this->Flash->error(__('No se pudo crear el evento'));
		}
		$profiles = $this->ProfilesGates->find('all')->contain('Profiles');
        $this->set(compact('sourcingEvent', 'profiles'));
    }

This is the code for add view:

<?php
/**
 * @var \App\View\AppView $this
 * @var \App\Model\Entity\SourcingEvent $sourcingEvent
 * @var \Cake\Collection\CollectionInterface|string[] $profiles
 */
?>
<div class="row">
    <div class="column-responsive column-80">
		<div class="sourcingEvents form content">
            <?= $this->Form->create($sourcingEvent) ?>
            <fieldset>
                <legend><?= __('Dar de alta evento de abastecimiento') ?></legend>
                <?php
					echo $this->Form->control('description',['label'=>'Descripción del evento']);
					echo $this->Form->button('Quitar selección',['type' => 'button', 'id' => 'quitar', 'class' => 'button float-right']);
					echo $this->Form->button('Seleccionar todos',['type' => 'button', 'id' => 'seleccionar', 'class' => 'button float-right']);
				?>
				<div class="table-responsive">
					<table>
						<thead>
							<tr>
								<th>Perfil</th>
								<th>Nodo</th>
								<th>Seleccionar</th>
							</tr>
						</thead>
						<tbody>
							<?php
								$i=0;
								foreach ($profiles as $profile):
									$color = '';
									switch ($profile->profile_id) {
										case '4':
											$color = '#6D147A';
											break;
										case '5':
											$color = '#CC7400';
											break;
										case '6':
											$color = '#2E2EBF';
											break;            
										default:
											$color = '#30773D';
											break;
									}
							?>
							<tr>
								<td align="center" style="background-color:<?= $color ?>;color:#fff"><?= $profile->profile->name ?></td>
								<td align="center"><?= !empty($profile->main_gate) ? '#'.$profile->main_gate : ' - ' ?></td>
								<td align="center">
									<?= $this->Form->checkbox('profiles.'.$i.'._joinData.profile_id', ['value'=>$profile->profile_id, 'hiddenField' => false, 'class' => 'profile']) ?>
									<?= $this->Form->hidden('profiles.'.$i.'._joinData.main_gate', ['value'=>$profile->main_gate]) ?>
								</td>
							</tr>
							<?php
									$i++;
								endforeach;
							?>
						</tbody>
					</table>
				</div>
            </fieldset>
            <?= $this->Form->button(__('Guardar')) ?>
			<?= $this->Form->end() ?>
		</div>
	</div>
</div>
<script>
$(function(){
	$('#seleccionar').click(function() {
		$('.profile').prop('checked', true);
	});
});
$(function(){
	$('#quitar').click(function() {
		$('.profile').prop('checked', false);
	});
});
</script>

And this is what it shows debug($sourcingEvent):

APP/Controller/SourcingEventsController.php (line 75)
object(App\Model\Entity\SourcingEvent) id:0 {
  'description' => 'Prueba de evento'
  'profiles' => [
    (int) 0 => object(App\Model\Entity\Profile) id:1 {
      '_joinData' => object(App\Model\Entity\SourcingEventsProfile) id:2 {
        'profile_id' => (int) 4
        '[new]' => true
        '[accessible]' => [
          'created' => true,
          'modified' => true,
          'sourcing_event' => true,
          'profile' => true,
          'sourcing_event_id' => true,
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[dirty]' => [
          'profile_id' => true,
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'SourcingEventsProfiles'
      }
      '[new]' => true
      '[accessible]' => [
        'name' => true,
        'description' => true,
        'referrer_profile_id' => true,
        'created' => true,
        'modified' => true,
        'profiles_gates' => true,
        'users' => true,
        'sourcing_events' => true,
      ]
      '[dirty]' => [
        '_joinData' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'Profiles'
    },
    (int) 1 => object(App\Model\Entity\Profile) id:3 {
      '_joinData' => object(App\Model\Entity\SourcingEventsProfile) id:4 {
        'profile_id' => (int) 5
        'main_gate' => 'A'
        '[new]' => true
        '[accessible]' => [
          'created' => true,
          'modified' => true,
          'sourcing_event' => true,
          'profile' => true,
          'sourcing_event_id' => true,
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[dirty]' => [
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'SourcingEventsProfiles'
      }
      '[new]' => true
      '[accessible]' => [
        'name' => true,
        'description' => true,
        'referrer_profile_id' => true,
        'created' => true,
        'modified' => true,
        'profiles_gates' => true,
        'users' => true,
        'sourcing_events' => true,
      ]
      '[dirty]' => [
        '_joinData' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'Profiles'
    },
    (int) 2 => object(App\Model\Entity\Profile) id:5 {
      '_joinData' => object(App\Model\Entity\SourcingEventsProfile) id:6 {
        'profile_id' => (int) 5
        'main_gate' => 'B'
        '[new]' => true
        '[accessible]' => [
          'created' => true,
          'modified' => true,
          'sourcing_event' => true,
          'profile' => true,
          'sourcing_event_id' => true,
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[dirty]' => [
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'SourcingEventsProfiles'
      }
      '[new]' => true
      '[accessible]' => [
        'name' => true,
        'description' => true,
        'referrer_profile_id' => true,
        'created' => true,
        'modified' => true,
        'profiles_gates' => true,
        'users' => true,
        'sourcing_events' => true,
      ]
      '[dirty]' => [
        '_joinData' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'Profiles'
    },
    (int) 3 => object(App\Model\Entity\Profile) id:7 {
      '_joinData' => object(App\Model\Entity\SourcingEventsProfile) id:8 {
        'profile_id' => (int) 6
        'main_gate' => 'A'
        '[new]' => true
        '[accessible]' => [
          'created' => true,
          'modified' => true,
          'sourcing_event' => true,
          'profile' => true,
          'sourcing_event_id' => true,
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[dirty]' => [
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'SourcingEventsProfiles'
      }
      '[new]' => true
      '[accessible]' => [
        'name' => true,
        'description' => true,
        'referrer_profile_id' => true,
        'created' => true,
        'modified' => true,
        'profiles_gates' => true,
        'users' => true,
        'sourcing_events' => true,
      ]
      '[dirty]' => [
        '_joinData' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'Profiles'
    },
    (int) 4 => object(App\Model\Entity\Profile) id:9 {
      '_joinData' => object(App\Model\Entity\SourcingEventsProfile) id:10 {
        'profile_id' => (int) 6
        'main_gate' => 'B'
        '[new]' => true
        '[accessible]' => [
          'created' => true,
          'modified' => true,
          'sourcing_event' => true,
          'profile' => true,
          'sourcing_event_id' => true,
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[dirty]' => [
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'SourcingEventsProfiles'
      }
      '[new]' => true
      '[accessible]' => [
        'name' => true,
        'description' => true,
        'referrer_profile_id' => true,
        'created' => true,
        'modified' => true,
        'profiles_gates' => true,
        'users' => true,
        'sourcing_events' => true,
      ]
      '[dirty]' => [
        '_joinData' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'Profiles'
    },
    (int) 5 => object(App\Model\Entity\Profile) id:11 {
      '_joinData' => object(App\Model\Entity\SourcingEventsProfile) id:12 {
        'profile_id' => (int) 7
        'main_gate' => 'A'
        '[new]' => true
        '[accessible]' => [
          'created' => true,
          'modified' => true,
          'sourcing_event' => true,
          'profile' => true,
          'sourcing_event_id' => true,
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[dirty]' => [
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'SourcingEventsProfiles'
      }
      '[new]' => true
      '[accessible]' => [
        'name' => true,
        'description' => true,
        'referrer_profile_id' => true,
        'created' => true,
        'modified' => true,
        'profiles_gates' => true,
        'users' => true,
        'sourcing_events' => true,
      ]
      '[dirty]' => [
        '_joinData' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'Profiles'
    },
    (int) 6 => object(App\Model\Entity\Profile) id:13 {
      '_joinData' => object(App\Model\Entity\SourcingEventsProfile) id:14 {
        'profile_id' => (int) 7
        'main_gate' => 'B'
        '[new]' => true
        '[accessible]' => [
          'created' => true,
          'modified' => true,
          'sourcing_event' => true,
          'profile' => true,
          'sourcing_event_id' => true,
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[dirty]' => [
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'SourcingEventsProfiles'
      }
      '[new]' => true
      '[accessible]' => [
        'name' => true,
        'description' => true,
        'referrer_profile_id' => true,
        'created' => true,
        'modified' => true,
        'profiles_gates' => true,
        'users' => true,
        'sourcing_events' => true,
      ]
      '[dirty]' => [
        '_joinData' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'Profiles'
    },
  ]
  '_joinData' => [
    (int) 0 => object(Cake\ORM\Entity) id:15 {
      'profile_id' => (int) 4
      'main_gate' => null
      '[new]' => true
      '[accessible]' => [
        '*' => true,
      ]
      '[dirty]' => [
        'profile_id' => true,
        'main_gate' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => ''
    },
    (int) 1 => object(Cake\ORM\Entity) id:16 {
      'profile_id' => (int) 5
      'main_gate' => 'A'
      '[new]' => true
      '[accessible]' => [
        '*' => true,
      ]
      '[dirty]' => [
        'profile_id' => true,
        'main_gate' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => ''
    },
    (int) 2 => object(Cake\ORM\Entity) id:17 {
      'profile_id' => (int) 5
      'main_gate' => 'B'
      '[new]' => true
      '[accessible]' => [
        '*' => true,
      ]
      '[dirty]' => [
        'profile_id' => true,
        'main_gate' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => ''
    },
    (int) 3 => object(Cake\ORM\Entity) id:18 {
      'profile_id' => (int) 6
      'main_gate' => 'A'
      '[new]' => true
      '[accessible]' => [
        '*' => true,
      ]
      '[dirty]' => [
        'profile_id' => true,
        'main_gate' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => ''
    },
    (int) 4 => object(Cake\ORM\Entity) id:19 {
      'profile_id' => (int) 6
      'main_gate' => 'B'
      '[new]' => true
      '[accessible]' => [
        '*' => true,
      ]
      '[dirty]' => [
        'profile_id' => true,
        'main_gate' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => ''
    },
    (int) 5 => object(Cake\ORM\Entity) id:20 {
      'profile_id' => (int) 7
      'main_gate' => 'A'
      '[new]' => true
      '[accessible]' => [
        '*' => true,
      ]
      '[dirty]' => [
        'profile_id' => true,
        'main_gate' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => ''
    },
    (int) 6 => object(Cake\ORM\Entity) id:21 {
      'profile_id' => (int) 7
      'main_gate' => 'B'
      '[new]' => true
      '[accessible]' => [
        '*' => true,
      ]
      '[dirty]' => [
        'profile_id' => true,
        'main_gate' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => ''
    },
  ]
  '[new]' => true
  '[accessible]' => [
    'description' => true,
    'created' => true,
    'modified' => true,
    'profiles' => true,
  ]
  '[dirty]' => [
    'description' => true,
    'profiles' => true,
    '_joinData' => true,
  ]
  '[original]' => [
  ]
  '[virtual]' => [
  ]
  '[hasErrors]' => false
  '[errors]' => [
  ]
  '[invalid]' => [
  ]
  '[repository]' => 'SourcingEvents'
}

Please answer me this question, I am stuck with this and can’t advance and my client is hurrying me, I’m gonna loose a good deal

It’s hard to decipher what exactly your problem actually is. That weird join data rebuilding also is kinda irritating. It might be easier if you’d show both, what the data looks like that you have, and what you’d want the data to look like instead. Remember that nobody here has any idea about the requirements of your application’s domains!

So, where exactly do these duplicate profile_id’s are causing a problem? In $profiles that you’re passing to the view? And then you get multiple join data records accordingly from your form and you don’t want that?

If that would be the case, then the question would be on what basis that would need to be reduced, like you are evaluating main_gate in the form, so I would assume that you can’t just randomly drop one of the records, eg why would you drop one with a main_gate of A over B or vice versa…

I need the profile_id’s to be repeated, this is what it shows debug($profiles):

ROOT/templates/SourcingEvents/add.php (line 7)
object(Cake\ORM\ResultSet) id:0 {
  'items' => [
    (int) 0 => object(App\Model\Entity\ProfilesGate) id:1 {
      'id' => (int) 1
      'profile_id' => (int) 4
      'main_gate' => null
      'created' => object(Cake\I18n\FrozenTime) id:2 {
        'time' => '2020-05-15 23:09:09.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'modified' => object(Cake\I18n\FrozenTime) id:3 {
        'time' => '2020-05-15 23:09:09.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'profile' => object(App\Model\Entity\Profile) id:4 {
        'id' => (int) 4
        'name' => 'Coordinador de UF'
        'description' => 'Coordinación de la unidad funcional del centro de salud'
        'referrer_profile_id' => (int) 3
        'created' => object(Cake\I18n\FrozenTime) id:5 {
          'time' => '2023-03-14 12:55:53.000000-03:00'
          'timezone' => 'America/Argentina/Cordoba'
          'fixedNowTime' => false
        }
        'modified' => object(Cake\I18n\FrozenTime) id:6 {
          'time' => '2023-03-14 12:55:53.000000-03:00'
          'timezone' => 'America/Argentina/Cordoba'
          'fixedNowTime' => false
        }
        '[new]' => false
        '[accessible]' => [
          'name' => true,
          'description' => true,
          'referrer_profile_id' => true,
          'created' => true,
          'modified' => true,
          'profiles_gates' => true,
          'users' => true,
          'sourcing_events' => true,
        ]
        '[dirty]' => [
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'Profiles'
      }
      '[new]' => false
      '[accessible]' => [
        'profile_id' => true,
        'main_gate' => true,
        'created' => true,
        'modified' => true,
        'profile' => true,
      ]
      '[dirty]' => [
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'ProfilesGates'
    },
    (int) 1 => object(App\Model\Entity\ProfilesGate) id:7 {
      'id' => (int) 2
      'profile_id' => (int) 5
      'main_gate' => 'A'
      'created' => object(Cake\I18n\FrozenTime) id:8 {
        'time' => '2020-05-15 23:11:08.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'modified' => object(Cake\I18n\FrozenTime) id:9 {
        'time' => '2020-05-15 23:11:08.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'profile' => object(App\Model\Entity\Profile) id:10 {
        'id' => (int) 5
        'name' => 'Responsable de nodo'
        'description' => 'Responsable de nodo A o B del centro de salud'
        'referrer_profile_id' => (int) 4
        'created' => object(Cake\I18n\FrozenTime) id:11 {
          'time' => '2023-03-14 12:56:49.000000-03:00'
          'timezone' => 'America/Argentina/Cordoba'
          'fixedNowTime' => false
        }
        'modified' => object(Cake\I18n\FrozenTime) id:12 {
          'time' => '2023-03-14 12:56:49.000000-03:00'
          'timezone' => 'America/Argentina/Cordoba'
          'fixedNowTime' => false
        }
        '[new]' => false
        '[accessible]' => [
          'name' => true,
          'description' => true,
          'referrer_profile_id' => true,
          'created' => true,
          'modified' => true,
          'profiles_gates' => true,
          'users' => true,
          'sourcing_events' => true,
        ]
        '[dirty]' => [
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'Profiles'
      }
      '[new]' => false
      '[accessible]' => [
        'profile_id' => true,
        'main_gate' => true,
        'created' => true,
        'modified' => true,
        'profile' => true,
      ]
      '[dirty]' => [
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'ProfilesGates'
    },
    (int) 2 => object(App\Model\Entity\ProfilesGate) id:13 {
      'id' => (int) 3
      'profile_id' => (int) 5
      'main_gate' => 'B'
      'created' => object(Cake\I18n\FrozenTime) id:14 {
        'time' => '2020-05-15 23:11:33.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'modified' => object(Cake\I18n\FrozenTime) id:15 {
        'time' => '2020-05-15 23:11:33.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'profile' => object(App\Model\Entity\Profile) id:16 {
        'id' => (int) 5
        'name' => 'Responsable de nodo'
        'description' => 'Responsable de nodo A o B del centro de salud'
        'referrer_profile_id' => (int) 4
        'created' => object(Cake\I18n\FrozenTime) id:17 {
          'time' => '2023-03-14 12:56:49.000000-03:00'
          'timezone' => 'America/Argentina/Cordoba'
          'fixedNowTime' => false
        }
        'modified' => object(Cake\I18n\FrozenTime) id:18 {
          'time' => '2023-03-14 12:56:49.000000-03:00'
          'timezone' => 'America/Argentina/Cordoba'
          'fixedNowTime' => false
        }
        '[new]' => false
        '[accessible]' => [
          'name' => true,
          'description' => true,
          'referrer_profile_id' => true,
          'created' => true,
          'modified' => true,
          'profiles_gates' => true,
          'users' => true,
          'sourcing_events' => true,
        ]
        '[dirty]' => [
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'Profiles'
      }
      '[new]' => false
      '[accessible]' => [
        'profile_id' => true,
        'main_gate' => true,
        'created' => true,
        'modified' => true,
        'profile' => true,
      ]
      '[dirty]' => [
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'ProfilesGates'
    },
    (int) 3 => object(App\Model\Entity\ProfilesGate) id:19 {
      'id' => (int) 4
      'profile_id' => (int) 6
      'main_gate' => 'A'
      'created' => object(Cake\I18n\FrozenTime) id:20 {
        'time' => '2020-05-15 23:12:01.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'modified' => object(Cake\I18n\FrozenTime) id:21 {
        'time' => '2020-05-15 23:12:01.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'profile' => object(App\Model\Entity\Profile) id:22 {
        'id' => (int) 6
        'name' => 'Operador Táctico'
        'description' => 'Asigna tareas a los agentes sanitarios'
        'referrer_profile_id' => (int) 5
        'created' => object(Cake\I18n\FrozenTime) id:23 {
          'time' => '2023-03-14 12:57:51.000000-03:00'
          'timezone' => 'America/Argentina/Cordoba'
          'fixedNowTime' => false
        }
        'modified' => object(Cake\I18n\FrozenTime) id:24 {
          'time' => '2023-03-14 12:57:51.000000-03:00'
          'timezone' => 'America/Argentina/Cordoba'
          'fixedNowTime' => false
        }
        '[new]' => false
        '[accessible]' => [
          'name' => true,
          'description' => true,
          'referrer_profile_id' => true,
          'created' => true,
          'modified' => true,
          'profiles_gates' => true,
          'users' => true,
          'sourcing_events' => true,
        ]
        '[dirty]' => [
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'Profiles'
      }
      '[new]' => false
      '[accessible]' => [
        'profile_id' => true,
        'main_gate' => true,
        'created' => true,
        'modified' => true,
        'profile' => true,
      ]
      '[dirty]' => [
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'ProfilesGates'
    },
    (int) 4 => object(App\Model\Entity\ProfilesGate) id:25 {
      'id' => (int) 5
      'profile_id' => (int) 6
      'main_gate' => 'B'
      'created' => object(Cake\I18n\FrozenTime) id:26 {
        'time' => '2020-05-15 23:12:40.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'modified' => object(Cake\I18n\FrozenTime) id:27 {
        'time' => '2020-05-15 23:12:40.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'profile' => object(App\Model\Entity\Profile) id:28 {
        'id' => (int) 6
        'name' => 'Operador Táctico'
        'description' => 'Asigna tareas a los agentes sanitarios'
        'referrer_profile_id' => (int) 5
        'created' => object(Cake\I18n\FrozenTime) id:29 {
          'time' => '2023-03-14 12:57:51.000000-03:00'
          'timezone' => 'America/Argentina/Cordoba'
          'fixedNowTime' => false
        }
        'modified' => object(Cake\I18n\FrozenTime) id:30 {
          'time' => '2023-03-14 12:57:51.000000-03:00'
          'timezone' => 'America/Argentina/Cordoba'
          'fixedNowTime' => false
        }
        '[new]' => false
        '[accessible]' => [
          'name' => true,
          'description' => true,
          'referrer_profile_id' => true,
          'created' => true,
          'modified' => true,
          'profiles_gates' => true,
          'users' => true,
          'sourcing_events' => true,
        ]
        '[dirty]' => [
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'Profiles'
      }
      '[new]' => false
      '[accessible]' => [
        'profile_id' => true,
        'main_gate' => true,
        'created' => true,
        'modified' => true,
        'profile' => true,
      ]
      '[dirty]' => [
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'ProfilesGates'
    },
    (int) 5 => object(App\Model\Entity\ProfilesGate) id:31 {
      'id' => (int) 6
      'profile_id' => (int) 7
      'main_gate' => 'A'
      'created' => object(Cake\I18n\FrozenTime) id:32 {
        'time' => '2020-05-15 23:13:18.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'modified' => object(Cake\I18n\FrozenTime) id:33 {
        'time' => '2020-05-15 23:13:18.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'profile' => object(App\Model\Entity\Profile) id:34 {
        'id' => (int) 7
        'name' => 'Agente sanitario'
        'description' => 'Realiza la vacunación y seguimiento de los pacientes'
        'referrer_profile_id' => (int) 6
        'created' => object(Cake\I18n\FrozenTime) id:35 {
          'time' => '2023-03-14 12:59:01.000000-03:00'
          'timezone' => 'America/Argentina/Cordoba'
          'fixedNowTime' => false
        }
        'modified' => object(Cake\I18n\FrozenTime) id:36 {
          'time' => '2023-03-14 12:59:01.000000-03:00'
          'timezone' => 'America/Argentina/Cordoba'
          'fixedNowTime' => false
        }
        '[new]' => false
        '[accessible]' => [
          'name' => true,
          'description' => true,
          'referrer_profile_id' => true,
          'created' => true,
          'modified' => true,
          'profiles_gates' => true,
          'users' => true,
          'sourcing_events' => true,
        ]
        '[dirty]' => [
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'Profiles'
      }
      '[new]' => false
      '[accessible]' => [
        'profile_id' => true,
        'main_gate' => true,
        'created' => true,
        'modified' => true,
        'profile' => true,
      ]
      '[dirty]' => [
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'ProfilesGates'
    },
    (int) 6 => object(App\Model\Entity\ProfilesGate) id:37 {
      'id' => (int) 7
      'profile_id' => (int) 7
      'main_gate' => 'B'
      'created' => object(Cake\I18n\FrozenTime) id:38 {
        'time' => '2020-05-15 23:13:43.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'modified' => object(Cake\I18n\FrozenTime) id:39 {
        'time' => '2020-05-15 23:13:43.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'profile' => object(App\Model\Entity\Profile) id:40 {
        'id' => (int) 7
        'name' => 'Agente sanitario'
        'description' => 'Realiza la vacunación y seguimiento de los pacientes'
        'referrer_profile_id' => (int) 6
        'created' => object(Cake\I18n\FrozenTime) id:41 {
          'time' => '2023-03-14 12:59:01.000000-03:00'
          'timezone' => 'America/Argentina/Cordoba'
          'fixedNowTime' => false
        }
        'modified' => object(Cake\I18n\FrozenTime) id:42 {
          'time' => '2023-03-14 12:59:01.000000-03:00'
          'timezone' => 'America/Argentina/Cordoba'
          'fixedNowTime' => false
        }
        '[new]' => false
        '[accessible]' => [
          'name' => true,
          'description' => true,
          'referrer_profile_id' => true,
          'created' => true,
          'modified' => true,
          'profiles_gates' => true,
          'users' => true,
          'sourcing_events' => true,
        ]
        '[dirty]' => [
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'Profiles'
      }
      '[new]' => false
      '[accessible]' => [
        'profile_id' => true,
        'main_gate' => true,
        'created' => true,
        'modified' => true,
        'profile' => true,
      ]
      '[dirty]' => [
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'ProfilesGates'
    },
  ]
}

As you can see there are 7 items, and 6 have profile_id repeated because of the two main_gates.
The problem is caused when I want to save the records because of the profile_id’s repeated.

I’m sorry, but I can’t really help you if you ignore most of my post.

Let me explain you, when I put

$sourcingEvent = $this->SourcingEvents->newEntity($this->request->getData(), [
'associated' => [
	'Profiles' => [
		'onlyIds' => true,
		[
			'_joinData' => [
				'accessibleFields' => ['sourcing_event_id' => true, 'profile_id' => true, 'main_gate' => true],
			]
		]
	]
]
]);

it doesn’t put the array profiles in sourcingEvent, and for that reason I put

if ($this->SourcingEvents->save($sourcingEvent, ['associated' => ['SourcingEventsProfiles']]))

but it doesn’t save the _joinData, what am I doing wrong?
This is what it shows debug($sourcingEvent) when I put ‘Profiles’ => [‘onlyIds’ => true]:

APP/Controller/SourcingEventsController.php (line 80)
object(App\Model\Entity\SourcingEvent) id:0 {
  'description' => 'Prueba de evento'
  'profiles' => [
  ]
  '[new]' => true
  '[accessible]' => [
    'description' => true,
    'created' => true,
    'modified' => true,
    'profiles' => true,
  ]
  '[dirty]' => [
    'description' => true,
    'profiles' => true,
  ]
  '[original]' => [
  ]
  '[virtual]' => [
  ]
  '[hasErrors]' => false
  '[errors]' => [
  ]
  '[invalid]' => [
  ]
  '[repository]' => 'SourcingEvents'
}

But it should look like this:

APP/Controller/SourcingEventsController.php (line 69)
object(App\Model\Entity\SourcingEvent) id:0 {
  'description' => 'Prueba de evento'
  'profiles' => [
    (int) 0 => object(App\Model\Entity\Profile) id:1 {
      '_joinData' => object(App\Model\Entity\SourcingEventsProfile) id:2 {
        'profile_id' => (int) 4
        'main_gate' => ''
        '[new]' => true
        '[accessible]' => [
          'sourcing_event_id' => true,
          'profile_id' => true,
          'main_gate' => true,
          'created' => true,
          'modified' => true,
          'sourcing_event' => true,
          'profile' => true,
        ]
        '[dirty]' => [
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'SourcingEventsProfiles'
      }
      '[new]' => true
      '[accessible]' => [
        'name' => true,
        'description' => true,
        'referrer_profile_id' => true,
        'created' => true,
        'modified' => true,
        'aro' => true,
        'referrer_profile' => true,
        'profiles_gates' => true,
        'users' => true,
        'sourcing_events' => true,
      ]
      '[dirty]' => [
        '_joinData' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'Profiles'
    },
    (int) 1 => object(App\Model\Entity\Profile) id:3 {
      '_joinData' => object(App\Model\Entity\SourcingEventsProfile) id:4 {
        'profile_id' => (int) 5
        'main_gate' => 'A'
        '[new]' => true
        '[accessible]' => [
          'sourcing_event_id' => true,
          'profile_id' => true,
          'main_gate' => true,
          'created' => true,
          'modified' => true,
          'sourcing_event' => true,
          'profile' => true,
        ]
        '[dirty]' => [
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'SourcingEventsProfiles'
      }
      '[new]' => true
      '[accessible]' => [
        'name' => true,
        'description' => true,
        'referrer_profile_id' => true,
        'created' => true,
        'modified' => true,
        'aro' => true,
        'referrer_profile' => true,
        'profiles_gates' => true,
        'users' => true,
        'sourcing_events' => true,
      ]
      '[dirty]' => [
        '_joinData' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'Profiles'
    },
    (int) 2 => object(App\Model\Entity\Profile) id:5 {
      '_joinData' => object(App\Model\Entity\SourcingEventsProfile) id:6 {
        'profile_id' => (int) 5
        'main_gate' => 'B'
        '[new]' => true
        '[accessible]' => [
          'sourcing_event_id' => true,
          'profile_id' => true,
          'main_gate' => true,
          'created' => true,
          'modified' => true,
          'sourcing_event' => true,
          'profile' => true,
        ]
        '[dirty]' => [
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'SourcingEventsProfiles'
      }
      '[new]' => true
      '[accessible]' => [
        'name' => true,
        'description' => true,
        'referrer_profile_id' => true,
        'created' => true,
        'modified' => true,
        'aro' => true,
        'referrer_profile' => true,
        'profiles_gates' => true,
        'users' => true,
        'sourcing_events' => true,
      ]
      '[dirty]' => [
        '_joinData' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'Profiles'
    },
    (int) 3 => object(App\Model\Entity\Profile) id:7 {
      '_joinData' => object(App\Model\Entity\SourcingEventsProfile) id:8 {
        'profile_id' => (int) 6
        'main_gate' => 'A'
        '[new]' => true
        '[accessible]' => [
          'sourcing_event_id' => true,
          'profile_id' => true,
          'main_gate' => true,
          'created' => true,
          'modified' => true,
          'sourcing_event' => true,
          'profile' => true,
        ]
        '[dirty]' => [
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'SourcingEventsProfiles'
      }
      '[new]' => true
      '[accessible]' => [
        'name' => true,
        'description' => true,
        'referrer_profile_id' => true,
        'created' => true,
        'modified' => true,
        'aro' => true,
        'referrer_profile' => true,
        'profiles_gates' => true,
        'users' => true,
        'sourcing_events' => true,
      ]
      '[dirty]' => [
        '_joinData' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'Profiles'
    },
    (int) 4 => object(App\Model\Entity\Profile) id:9 {
      '_joinData' => object(App\Model\Entity\SourcingEventsProfile) id:10 {
        'profile_id' => (int) 6
        'main_gate' => 'B'
        '[new]' => true
        '[accessible]' => [
          'sourcing_event_id' => true,
          'profile_id' => true,
          'main_gate' => true,
          'created' => true,
          'modified' => true,
          'sourcing_event' => true,
          'profile' => true,
        ]
        '[dirty]' => [
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'SourcingEventsProfiles'
      }
      '[new]' => true
      '[accessible]' => [
        'name' => true,
        'description' => true,
        'referrer_profile_id' => true,
        'created' => true,
        'modified' => true,
        'aro' => true,
        'referrer_profile' => true,
        'profiles_gates' => true,
        'users' => true,
        'sourcing_events' => true,
      ]
      '[dirty]' => [
        '_joinData' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'Profiles'
    },
    (int) 5 => object(App\Model\Entity\Profile) id:11 {
      '_joinData' => object(App\Model\Entity\SourcingEventsProfile) id:12 {
        'profile_id' => (int) 7
        'main_gate' => 'A'
        '[new]' => true
        '[accessible]' => [
          'sourcing_event_id' => true,
          'profile_id' => true,
          'main_gate' => true,
          'created' => true,
          'modified' => true,
          'sourcing_event' => true,
          'profile' => true,
        ]
        '[dirty]' => [
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'SourcingEventsProfiles'
      }
      '[new]' => true
      '[accessible]' => [
        'name' => true,
        'description' => true,
        'referrer_profile_id' => true,
        'created' => true,
        'modified' => true,
        'aro' => true,
        'referrer_profile' => true,
        'profiles_gates' => true,
        'users' => true,
        'sourcing_events' => true,
      ]
      '[dirty]' => [
        '_joinData' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'Profiles'
    },
    (int) 6 => object(App\Model\Entity\Profile) id:13 {
      '_joinData' => object(App\Model\Entity\SourcingEventsProfile) id:14 {
        'profile_id' => (int) 7
        'main_gate' => 'B'
        '[new]' => true
        '[accessible]' => [
          'sourcing_event_id' => true,
          'profile_id' => true,
          'main_gate' => true,
          'created' => true,
          'modified' => true,
          'sourcing_event' => true,
          'profile' => true,
        ]
        '[dirty]' => [
          'profile_id' => true,
          'main_gate' => true,
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'SourcingEventsProfiles'
      }
      '[new]' => true
      '[accessible]' => [
        'name' => true,
        'description' => true,
        'referrer_profile_id' => true,
        'created' => true,
        'modified' => true,
        'aro' => true,
        'referrer_profile' => true,
        'profiles_gates' => true,
        'users' => true,
        'sourcing_events' => true,
      ]
      '[dirty]' => [
        '_joinData' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'Profiles'
    },
  ]
  '_joinData' => [
    (int) 0 => object(Cake\ORM\Entity) id:15 {
      'profile_id' => (int) 4
      'main_gate' => ''
      '[new]' => true
      '[accessible]' => [
        '*' => true,
      ]
      '[dirty]' => [
        'profile_id' => true,
        'main_gate' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => ''
    },
    (int) 1 => object(Cake\ORM\Entity) id:16 {
      'profile_id' => (int) 5
      'main_gate' => 'A'
      '[new]' => true
      '[accessible]' => [
        '*' => true,
      ]
      '[dirty]' => [
        'profile_id' => true,
        'main_gate' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => ''
    },
    (int) 2 => object(Cake\ORM\Entity) id:17 {
      'profile_id' => (int) 5
      'main_gate' => 'B'
      '[new]' => true
      '[accessible]' => [
        '*' => true,
      ]
      '[dirty]' => [
        'profile_id' => true,
        'main_gate' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => ''
    },
    (int) 3 => object(Cake\ORM\Entity) id:18 {
      'profile_id' => (int) 6
      'main_gate' => 'A'
      '[new]' => true
      '[accessible]' => [
        '*' => true,
      ]
      '[dirty]' => [
        'profile_id' => true,
        'main_gate' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => ''
    },
    (int) 4 => object(Cake\ORM\Entity) id:19 {
      'profile_id' => (int) 6
      'main_gate' => 'B'
      '[new]' => true
      '[accessible]' => [
        '*' => true,
      ]
      '[dirty]' => [
        'profile_id' => true,
        'main_gate' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => ''
    },
    (int) 5 => object(Cake\ORM\Entity) id:20 {
      'profile_id' => (int) 7
      'main_gate' => 'A'
      '[new]' => true
      '[accessible]' => [
        '*' => true,
      ]
      '[dirty]' => [
        'profile_id' => true,
        'main_gate' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => ''
    },
    (int) 6 => object(Cake\ORM\Entity) id:21 {
      'profile_id' => (int) 7
      'main_gate' => 'B'
      '[new]' => true
      '[accessible]' => [
        '*' => true,
      ]
      '[dirty]' => [
        'profile_id' => true,
        'main_gate' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => ''
    },
  ]
  '[new]' => true
  '[accessible]' => [
    'description' => true,
    'created' => true,
    'modified' => true,
    'profiles' => true,
  ]
  '[dirty]' => [
    'description' => true,
    'profiles' => true,
    '_joinData' => true,
  ]
  '[original]' => [
  ]
  '[virtual]' => [
  ]
  '[hasErrors]' => false
  '[errors]' => [
  ]
  '[invalid]' => [
  ]
  '[repository]' => 'SourcingEvents'
}

Can anyone please help me? I have to solve this issue as soon as possible and don’t know how to do it

I haven’t really put much thinking power into this but things I would check would be

  • make sure all the properties in all the used entity classes are set as accessible (you can pin them down later if you want to)
    I usually do something like
protected $_accessible = [
    '*' => true,
    'id' => false,
]
  • try to build a “static” array just in PHP which works and saves how you would like it. Then try to recreate a form which returns that array in the same way. So basically make sure your model is behaving as you desire it and then adjust the view to do exactly what you want.

Also see James McDonald’s Video related to _joinData here. Maybe there is something in there that helps you.

Thank you Kevin, I saw the video and changed the way of creating the Cake\Orm\Entity to add the _joinData, but the problem is in $this->request->getData(), I don’t know how to define the form controls to allow the addition of repeated profile ids, when I do debug($sourcingEvent) the profiles entity is empty, this happens when I put $sourcingEvent = $this->SourcingEvents->newEntity($this->request->getData(), [‘associated’ => [‘Profiles’ => [‘onlyIds’ => true]]]), when I don’t put the onlyIds is trying to save the profile and gives an exception with afterSave method in ProfilesTable.php.
This is the code for add view:

<?php
/**
 * @var \App\View\AppView $this
 * @var \App\Model\Entity\SourcingEvent $sourcingEvent
 * @var \Cake\Collection\CollectionInterface|string[] $profiles
 */
?>
<div class="row">
    <div class="column-responsive column-80">
		<div class="sourcingEvents form content">
            <?= $this->Form->create($sourcingEvent) ?>
            <fieldset>
                <legend><?= __('Agregar evento de abastecimiento') ?></legend>
                <?php
					echo $this->Form->control('description',['label'=>'Descripción del evento']);
					echo $this->Form->button('Quitar selección',['type' => 'button', 'id' => 'quitar', 'class' => 'button float-right']);
					echo $this->Form->button('Seleccionar todos',['type' => 'button', 'id' => 'seleccionar', 'class' => 'button float-right']);
				?>
				<div class="table-responsive">
					<table>
						<thead>
							<tr>
								<th>Perfil</th>
								<th>Nodo</th>
								<th>Seleccionar</th>
							</tr>
						</thead>
						<tbody>
							<?php
								$i=0;
								foreach ($profiles as $profile):
									$color = '';
									switch ($profile->profile_id) {
										case '4':
											$color = '#6D147A';
											break;
										case '5':
											$color = '#CC7400';
											break;
										case '6':
											$color = '#2E2EBF';
											break;            
										default:
											$color = '#30773D';
											break;
									}
							?>
							<tr>
								<td align="center" style="background-color:<?= $color ?>;color:#fff"><?= $profile->profile->name ?></td>
								<td align="center"><?= !empty($profile->main_gate) ? '#'.$profile->main_gate : ' - ' ?></td>
								<td align="center">
									<?= $this->Form->checkbox('profiles._ids[]', ['value'=>$profile->profile_id, 'hiddenField' => false, 'class' => 'profile']) ?>
									<?= $this->Form->hidden('profiles.'.$i.'._joinData.main_gate', ['value'=>$profile->main_gate]) ?>
								</td>
							</tr>
							<?php
									$i++;
								endforeach;
							?>
						</tbody>
					</table>
				</div>
            </fieldset>
            <?= $this->Form->button(__('Guardar')) ?>
			<?= $this->Form->end() ?>
		</div>
	</div>
</div>
<script>
$(function(){
	$('#seleccionar').click(function() {
		$('.profile').prop('checked', true);
	});
});
$(function(){
	$('#quitar').click(function() {
		$('.profile').prop('checked', false);
	});
});
</script>

And this is what it shows debug($sourcingEvent) without the onlyIds => true:

APP/Controller/SourcingEventsController.php (line 66)
object(App\Model\Entity\SourcingEvent) id:0 {
  'description' => 'Prueba de evento'
  'profiles' => [
    (int) 0 => object(App\Model\Entity\Profile) id:1 {
      'id' => (int) 4
      'name' => 'Coordinador de UF'
      'description' => 'Coordinación de la unidad funcional del centro de salud'
      'referrer_profile_id' => (int) 3
      'created' => object(Cake\I18n\FrozenTime) id:2 {
        'time' => '2023-03-14 12:55:53.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'modified' => object(Cake\I18n\FrozenTime) id:3 {
        'time' => '2023-03-14 12:55:53.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      '_joinData' => object(Cake\ORM\Entity) id:4 {
        'main_gate' => ''
        '[new]' => true
        '[accessible]' => [
          '*' => true,
        ]
        '[dirty]' => [
          'main_gate' => true,
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => ''
      }
      '[new]' => false
      '[accessible]' => [
        'name' => true,
        'description' => true,
        'referrer_profile_id' => true,
        'created' => true,
        'modified' => true,
        'aro' => true,
        'referrer_profile' => true,
        'profiles_gates' => true,
        'users' => true,
        'sourcing_events' => true,
      ]
      '[dirty]' => [
        '_joinData' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'Profiles'
    },
    (int) 1 => object(App\Model\Entity\Profile) id:5 {
      'id' => (int) 5
      'name' => 'Responsable de nodo'
      'description' => 'Responsable de nodo A o B del centro de salud'
      'referrer_profile_id' => (int) 4
      'created' => object(Cake\I18n\FrozenTime) id:6 {
        'time' => '2023-03-14 12:56:49.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'modified' => object(Cake\I18n\FrozenTime) id:7 {
        'time' => '2023-03-14 12:56:49.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      '_joinData' => object(Cake\ORM\Entity) id:8 {
        'main_gate' => 'A'
        '[new]' => true
        '[accessible]' => [
          '*' => true,
        ]
        '[dirty]' => [
          'main_gate' => true,
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => ''
      }
      '[new]' => false
      '[accessible]' => [
        'name' => true,
        'description' => true,
        'referrer_profile_id' => true,
        'created' => true,
        'modified' => true,
        'aro' => true,
        'referrer_profile' => true,
        'profiles_gates' => true,
        'users' => true,
        'sourcing_events' => true,
      ]
      '[dirty]' => [
        '_joinData' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'Profiles'
    },
    (int) 2 => object(App\Model\Entity\Profile) id:9 {
      'id' => (int) 6
      'name' => 'Operador Táctico'
      'description' => 'Asigna tareas a los agentes sanitarios'
      'referrer_profile_id' => (int) 5
      'created' => object(Cake\I18n\FrozenTime) id:10 {
        'time' => '2023-03-14 12:57:51.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'modified' => object(Cake\I18n\FrozenTime) id:11 {
        'time' => '2023-03-14 12:57:51.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      '_joinData' => object(Cake\ORM\Entity) id:12 {
        'main_gate' => 'B'
        '[new]' => true
        '[accessible]' => [
          '*' => true,
        ]
        '[dirty]' => [
          'main_gate' => true,
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => ''
      }
      '[new]' => false
      '[accessible]' => [
        'name' => true,
        'description' => true,
        'referrer_profile_id' => true,
        'created' => true,
        'modified' => true,
        'aro' => true,
        'referrer_profile' => true,
        'profiles_gates' => true,
        'users' => true,
        'sourcing_events' => true,
      ]
      '[dirty]' => [
        '_joinData' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'Profiles'
    },
    (int) 3 => object(App\Model\Entity\Profile) id:13 {
      'id' => (int) 7
      'name' => 'Agente sanitario'
      'description' => 'Realiza la vacunación y seguimiento de los pacientes'
      'referrer_profile_id' => (int) 6
      'created' => object(Cake\I18n\FrozenTime) id:14 {
        'time' => '2023-03-14 12:59:01.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'modified' => object(Cake\I18n\FrozenTime) id:15 {
        'time' => '2023-03-14 12:59:01.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      '_joinData' => object(Cake\ORM\Entity) id:16 {
        'main_gate' => 'A'
        '[new]' => true
        '[accessible]' => [
          '*' => true,
        ]
        '[dirty]' => [
          'main_gate' => true,
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => ''
      }
      '[new]' => false
      '[accessible]' => [
        'name' => true,
        'description' => true,
        'referrer_profile_id' => true,
        'created' => true,
        'modified' => true,
        'aro' => true,
        'referrer_profile' => true,
        'profiles_gates' => true,
        'users' => true,
        'sourcing_events' => true,
      ]
      '[dirty]' => [
        '_joinData' => true,
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'Profiles'
    },
  ]
  '[new]' => true
  '[accessible]' => [
    'description' => true,
    'created' => true,
    'modified' => true,
    'profiles' => true,
  ]
  '[dirty]' => [
    'description' => true,
    'profiles' => true,
  ]
  '[original]' => [
  ]
  '[virtual]' => [
  ]
  '[hasErrors]' => false
  '[errors]' => [
  ]
  '[invalid]' => [
  ]
  '[repository]' => 'SourcingEvents'
}

This is the code for add action:

    public function add()
    {
		$this->loadModel("ProfilesGates");
        $sourcingEvent = $this->SourcingEvents->newEmptyEntity();
		if ($this->request->is('post')) {
			$sourcingEvent = $this->SourcingEvents->patchEntity($sourcingEvent, $this->request->getData(), ['associated' => ['Profiles' => ['onlyIds' => true]]]);
			if(!empty($sourcingEvent->profiles)) {
				foreach($sourcingEvent->profiles as $key => $profile){
					if(!empty($profile->id)){
						$main_gate = $this->request->getData('profiles.'.$key.'._joinData.main_gate');
						$profile->_joinData = new Entity(['main_gate' => $main_gate], ['markNew' => true]);
					}
				}
			}
			debug($sourcingEvent);
			if ($this->SourcingEvents->save($sourcingEvent)) {
				$this->Flash->success(__('El evento ha sido creado'));
				return $this->redirect(array('action' => 'index'));
			}
			$this->Flash->error(__('No se pudo crear el evento'));
		}
		$profiles = $this->ProfilesGates->find('all')->contain('Profiles');
        $this->set(compact('sourcingEvent', 'profiles'));
    }

For some reason is giving me this exception:


For that reason it doesn’t save anything, how can I solve this issue?

You seem to have a afterSave() method inside your src/Model/Table/ProfilesTable.php which doesn’t have a correct parameter type.
It should be

public function afterSave(EventInterface $event, EntityInterface $entity, ArrayObject $options): void

with the following use statements at the top of your class

use Cake\Event\EventInterface;
use Cake\Datasource\EntityInterface;
use ArrayObject;

if you look at the error it clearly states

Argument 2 passed to App\Model\Table\ProfilesTable::afterSave() must be an instance of App\Model\Table\Entity

this in indicates you have something like

public function afterSave(EventInterface $event, Entity $entity, ArrayObject $options): void

WITHOUT any use statements at the top of class clarifying what exactly that Entity class is - therfore going “relative” to the current namespace which is App\Model\Table since you are in a Table class.

Thank you Kevin, that solved the exception with afterSave, but I still have another problem, it doesn’t save the repeated profile ids, it only saves the profile ids with main_gate A, the others with main_gate B doesn’t save them, how do I have to do to allow the addition of repeated profile ids?

Can anyone help me with this issue? I need to save repeated profile ids in the belongstomany join table, because there are three profile ids that have two main_gates (A and B), how can I do that?