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?

I really need help with this, please can anyone help me? I don’t know how to solve this issue

Please help me with this issue, I am stuck with this and can’t advance with the development of the site

It would be the easiest if you could create a very basic app reconstructing your problem and push it to a public repo so we can check it out.
Without that its basically impossible to help you here.

In that repo I put the controller, the view and the tables involved in that operation?

I published the repo in github, the url is https://github.com/mdeanquin0520/public_repo.git
In that repo are three folders: bd, src and templates, in folder bd is the file estadoatulado.sql, in that file are the structure and data of the tables needed for the operation.
The action to execute is add.

your provided code is missing parts. You need to provide the profiles table as well with its related code (at least the model) since your add method uses that model.

Besides the fact that I just had to manually remove the whole auth component and a bunch of your code in the AppController because how should I log into your app locally with that.

I added the profiles and the users table, the users controller and the views so that you can login, the username is mdeanquin@gmail.com and the password is lytfvn24108508

The link you should click on is Eventos de abastecimiento in menu “Gestión de personal y pacientes”