Set index for belongstomany join table in index view

So, groups_users is there, it’s just empty because this user has no groups.

Yes, that’s right, it has no groups

So… it’s working fine now?

No, is still not working

Can you show debug results for a user entity that should have groups?

This is the debug($user) for a user with one group:

ROOT/templates/Users/index.php (line 47)
object(App\Model\Entity\User) id:0 {
  'id' => (int) 4
  'username' => 'alejandro.ambrosini@unc.edu.ar'
  'password' => '$2y$10$LHXJASEVrCcHRX5jkAqLP.o.zxJPfDJUnSxC3HXOhBAXXbhzv0JWq'
  'email' => 'alejandro.ambrosini@unc.edu.ar'
  'firstname' => 'Alejandro'
  'lastname' => 'Ambrosini'
  'created' => object(Cake\I18n\FrozenTime) id:1 {
    'time' => '2023-03-31 16:49:48.000000-03:00'
    'timezone' => 'America/Argentina/Cordoba'
    'fixedNowTime' => false
  }
  'modified' => object(Cake\I18n\FrozenTime) id:2 {
    'time' => '2023-04-02 21:35:19.000000-03:00'
    'timezone' => 'America/Argentina/Cordoba'
    'fixedNowTime' => false
  }
  'profile_id' => (int) 4
  'referrer_id' => (int) 3
  'active' => true
  'image_file_name_url' => 'https://www.estadoatulado.com.ar/upload/Users/ale_original.jpg'
  'image_file_name' => '/home/o12mg0png743/public_html/estadoatulado.com.ar/webroot/upload/Users/ale_original.jpg'
  'image_file_name_filename' => 'ale_original.jpg'
  'map_lat' => '-31.383650007680200'
  'map_long' => '-64.243868229332920'
  'code' => '1234567890'
  'status' => (int) 0
  'isolated' => false
  'token' => null
  'groups_users' => [
    (int) 0 => object(App\Model\Entity\GroupsUser) id:3 {
      'user_id' => (int) 4
      'group_id' => (int) 1
      'net_id' => (int) 1
      'main_gate' => ''
      'created' => object(Cake\I18n\FrozenTime) id:4 {
        'time' => '2023-03-31 16:49:48.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'modified' => object(Cake\I18n\FrozenTime) id:5 {
        'time' => '2023-03-31 16:49:48.000000-03:00'
        'timezone' => 'America/Argentina/Cordoba'
        'fixedNowTime' => false
      }
      'net' => object(App\Model\Entity\Net) id:6 {
        'id' => (int) 1
        'net_name' => 'UF No. 1'
        'group_id' => (int) 1
        'created' => object(Cake\I18n\FrozenTime) id:7 {
          'time' => '2023-03-23 12:14:27.000000-03:00'
          'timezone' => 'America/Argentina/Cordoba'
          'fixedNowTime' => false
        }
        'modified' => object(Cake\I18n\FrozenTime) id:8 {
          'time' => '2023-03-23 12:14:27.000000-03:00'
          'timezone' => 'America/Argentina/Cordoba'
          'fixedNowTime' => false
        }
        '[new]' => false
        '[accessible]' => [
          'net_name' => true,
          'group_id' => true,
          'created' => true,
          'modified' => true,
          'group' => true,
          'statesx_days' => true,
          'events' => true,
          'groups_users' => true,
          'pacients' => true,
          'orders' => true,
          'status_groups' => true,
          'stocks_users' => true,
          'turns' => true,
        ]
        '[dirty]' => [
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'Nets'
      }
      'group' => object(App\Model\Entity\Group) id:9 {
        'id' => (int) 1
        'group_name' => 'Célula 1'
        'created' => object(Cake\I18n\FrozenTime) id:10 {
          'time' => '2023-03-23 12:03:57.000000-03:00'
          'timezone' => 'America/Argentina/Cordoba'
          'fixedNowTime' => false
        }
        'modified' => object(Cake\I18n\FrozenTime) id:11 {
          'time' => '2023-04-06 00:39:45.000000-03:00'
          'timezone' => 'America/Argentina/Cordoba'
          'fixedNowTime' => false
        }
        '[new]' => false
        '[accessible]' => [
          'group_name' => true,
          'created' => true,
          'modified' => true,
          'statesx_days' => true,
          'events' => true,
          'nets' => true,
          'pacients' => true,
          'orders' => true,
          'status_groups' => true,
          'stocks_users' => true,
          'turns' => true,
          'users' => true,
        ]
        '[dirty]' => [
        ]
        '[original]' => [
        ]
        '[virtual]' => [
        ]
        '[hasErrors]' => false
        '[errors]' => [
        ]
        '[invalid]' => [
        ]
        '[repository]' => 'Groups'
      }
      '[new]' => false
      '[accessible]' => [
        'net_id' => true,
        'main_gate' => true,
        'created' => true,
        'modified' => true,
        'user' => true,
        'group' => true,
        'net' => true,
      ]
      '[dirty]' => [
      ]
      '[original]' => [
      ]
      '[virtual]' => [
      ]
      '[hasErrors]' => false
      '[errors]' => [
      ]
      '[invalid]' => [
      ]
      '[repository]' => 'GroupsUsers'
    },
  ]
  'referrer' => object(App\Model\Entity\User) id:12 {
    'id' => (int) 3
    'username' => 'cayojcs@gmail.com'
    'password' => '$2y$10$73p1Tioo9uc3y8bS5mRP8eaNyH0PGS5qmbBHcGK3ITZZlMjANwska'
    'email' => 'cayojcs@gmail.com'
    'firstname' => 'Julio Cesar'
    'lastname' => 'Sarmiento'
    'created' => object(Cake\I18n\FrozenTime) id:13 {
      'time' => '2023-03-23 13:14:49.000000-03:00'
      'timezone' => 'America/Argentina/Cordoba'
      'fixedNowTime' => false
    }
    'modified' => object(Cake\I18n\FrozenTime) id:14 {
      'time' => '2023-04-02 01:15:07.000000-03:00'
      'timezone' => 'America/Argentina/Cordoba'
      'fixedNowTime' => false
    }
    'profile_id' => (int) 3
    'referrer_id' => (int) 2
    'active' => true
    'image_file_name_url' => 'https://www.estadoatulado.com.ar/upload/Users/c2c11db8_c9cd_44fd_9c6a_556f2bd7028f_original.jpg'
    'image_file_name' => '/home/o12mg0png743/public_html/estadoatulado.com.ar/webroot/upload/Users/c2c11db8_c9cd_44fd_9c6a_556f2bd7028f_original.jpg'
    'image_file_name_filename' => 'c2c11db8_c9cd_44fd_9c6a_556f2bd7028f_original.jpg'
    'map_lat' => null
    'map_long' => null
    'code' => '1234567890'
    'status' => (int) 0
    'isolated' => false
    'token' => null
    '[new]' => false
    '[accessible]' => [
      'username' => true,
      'password' => true,
      'email' => true,
      'firstname' => true,
      'lastname' => true,
      'full_name' => true,
      'created' => true,
      'modified' => true,
      'profile_id' => true,
      'referrer_id' => true,
      'active' => true,
      'image_file_name_url' => true,
      'image_file_name' => true,
      'image_file_name_filename' => true,
      'map_lat' => true,
      'map_long' => true,
      'code' => true,
      'status' => true,
      'isolated' => true,
      'token' => true,
      'aro' => true,
      'profile' => true,
      'referrer' => true,
      'statesx_days' => true,
      'doctors' => true,
      'events_users' => true,
      'observations' => true,
      'pacients' => true,
      'status_groups' => true,
      'stocks_users' => true,
      'turns' => true,
      'doctorT' => true,
      'groups' => true,
    ]
    '[dirty]' => [
    ]
    '[original]' => [
    ]
    '[virtual]' => [
    ]
    '[hasErrors]' => false
    '[errors]' => [
    ]
    '[invalid]' => [
    ]
    '[repository]' => 'Referrer'
  }
  'profile' => object(App\Model\Entity\Profile) id:15 {
    '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:16 {
      'time' => '2023-03-14 12:55:53.000000-03:00'
      'timezone' => 'America/Argentina/Cordoba'
      'fixedNowTime' => false
    }
    'modified' => object(Cake\I18n\FrozenTime) id:17 {
      'time' => '2023-05-13 14:49:00.000000-03:00'
      'timezone' => 'America/Argentina/Cordoba'
      'fixedNowTime' => false
    }
    '[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]' => [
    ]
    '[original]' => [
    ]
    '[virtual]' => [
    ]
    '[hasErrors]' => false
    '[errors]' => [
    ]
    '[invalid]' => [
    ]
    '[repository]' => 'Profiles'
  }
  '[new]' => false
  '[accessible]' => [
    'username' => true,
    'password' => true,
    'email' => true,
    'firstname' => true,
    'lastname' => true,
    'full_name' => true,
    'created' => true,
    'modified' => true,
    'profile_id' => true,
    'referrer_id' => true,
    'active' => true,
    'image_file_name_url' => true,
    'image_file_name' => true,
    'image_file_name_filename' => true,
    'map_lat' => true,
    'map_long' => true,
    'code' => true,
    'status' => true,
    'isolated' => true,
    'token' => true,
    'aro' => true,
    'profile' => true,
    'referrer' => true,
    'statesx_days' => true,
    'doctors' => true,
    'events_users' => true,
    'observations' => true,
    'pacients' => true,
    'status_groups' => true,
    'stocks_users' => true,
    'turns' => true,
    'doctorT' => true,
    'groups' => true,
  ]
  '[dirty]' => [
  ]
  '[original]' => [
  ]
  '[virtual]' => [
  ]
  '[hasErrors]' => false
  '[errors]' => [
  ]
  '[invalid]' => [
  ]
  '[repository]' => 'Users'
}

So $user->groups_users is, as expected, an array of all the GroupsUsers records belonging to this user (in this case, just one such record). What do you need to get out of this that you don’t think is readily available now?

I don’t know how to define the association between users with groupsusers and groups with groupsusers so that it shows all the groups of a user when this has more than one group

It’s all right there in your data. Something like

foreach ($user->groups_users as $group_user) {
    // Do things with $group_user->group which is the Group entity, like ->id or ->group_name
    // Do things with $group_user->net, which is the Net entity, like ->id or ->net_name
}

Yes, I am doing it this way:

foreach ($user->groups_users as $groups_users):
	$mostrarGroup = (!empty($checkGV1) || !empty($checkGV2) || !empty($checkGV3) || !empty($checkGV4) || !empty($checkGV5)) ? 
		$this->Html->link($groups_users->group->group_name, ['controller' => 'Groups', 'action' => 'view', $groups_users->group->id]) : 
		h($groups_users->group->group_name);
	$group .= $this->Html->tag("p", $mostrarGroup);
	if(!empty($groups_users->net_id)){
		$net = (!empty($checkNV1) || !empty($checkNV2) || !empty($checkNV3) || !empty($checkNV4) || !empty($checkNV5)) ? 
			$this->Html->link($groups_users->net->net_name, ['controller' => 'Nets', 'action' => 'view', 
			$groups_users->net_id]) : h($groups->net->net_name);
	}
	$gate = $groups_users->main_gate;
endforeach;

But for some reason it doesn’t show the groups of a user when this has more than one group.

This code is creating variables, but not generating any output at all; there’s not a single echo here.

Here are the echoes:

if($user->has("groups_users")):
	foreach ($user->groups_users as $group_user):
		$mostrarGroup = (!empty($checkGV1) || !empty($checkGV2) || !empty($checkGV3) || !empty($checkGV4) || !empty($checkGV5)) ? 
			$this->Html->link($group_user->group->group_name, ['controller' => 'Groups', 'action' => 'view', $group_user->group->id]) : 
			h($group_user->group->group_name);
		$group .= $this->Html->tag("p", $mostrarGroup);
		if(!empty($group_user->net_id)){
			$net = (!empty($checkNV1) || !empty($checkNV2) || !empty($checkNV3) || !empty($checkNV4) || !empty($checkNV5)) ? 
				$this->Html->link($group_user->net->net_name, ['controller' => 'Nets', 'action' => 'view', 
				$group_user->net_id]) : h($group_user->net->net_name);
		}
		$gate = $group_user->main_gate;
	endforeach;
endif;
?>
<tr>
    <td><?= $user->image_file_name_url === null ? '' : $this->Html->image($user->image_file_name_url, ['class' => 'img-circle']) ?></td>
    <td><?= h($user->username) ?></td>
    <td><?= h($user->email) ?></td>
    <td><?= h($user->firstname) ?></td>
    <td><?= h($user->lastname) ?></td>
    <td><?= h($user->created) ?></td>
    <td><?= h($user->modified) ?></td>
    <td style="background-color:<?= $color ?>;color:#fff"><?= $user->has('profile') ? !empty($checkPrV1) || !empty($checkPrV2) || 
!empty($checkPrV3) || !empty($checkPrV4) || !empty($checkPrV5) ? $this->Html->link($user->profile->name, ['controller' => 'Profiles', 
'action' => 'view', $user->profile->id]) : h($user->profile->name) : '' ?></td>
<td><?= (!empty($group)) ? $group : '' ?></td>
    <td><?= (!empty($net)) ? $net : '' ?></td>
    <td><?= (!empty($gate)) ? h($gate) : '' ?></td>
    <td><?= $user->has('referrer') ? !empty($checkUV1) || !empty($checkUV2) || !empty($checkUV3) || !empty($checkUV4) || !empty($checkUV5) ?
	$this->Html->link($user->referrer->full_name, ['controller' => 'Users', 'action' => 'view', $user->referrer->id]) :
	h($user->referrer->full_name) : '' ?></td>
    <td><?= h($user->active) ?></td>
    <td><?= $user->map_lat === null ? '' : $this->Number->format($user->map_lat) ?></td>
    <td><?= $user->map_long === null ? '' : $this->Number->format($user->map_long) ?></td>
    <td style="background-color:<?= $colorAlert ?>;"><?php echo $statusAlertEnum[$user->status]; ?></td> 
    <td><?= $user->isolated === null ? '' : $this->Number->format($user->isolated) ?></td>
    <td class="actions">
        <?= !empty($checkUC1) || !empty($checkUC2) ? $this->Html->link($this->Html->tag("span", "", ['class'=>'glyphicon glyphicon-user']), 
		['action' => 'changepassword', $user->id], ['escape' => false, 'title' => 'Cambiar contraseña']) : '' ?>
<?= !empty($checkUS1) || !empty($checkUS2) ? $this->Html->link($this->Html->tag("span", "", ['class'=>'glyphicon glyphicon-globe']), 
		['action' => 'setgeo', $user->id], ['escape' => false, 'title' => 'Setear geolocalización']) : '' ?>
        <?= !empty($checkUV1) || !empty($checkUV2) || !empty($checkUV3) || !empty($checkUV4) || !empty($checkUV5) ?
		$this->Html->link($this->Html->tag("span", "", ['class'=>'glyphicon glyphicon-search']), ['action' => 'view', $user->id], 
		['escape' => false, 'title' => 'Ver']) : '' ?>
        <?= !empty($checkUE1) || !empty($checkUE2) ? $this->Html->link($this->Html->tag("span", "", ['class'=>'glyphicon glyphicon-edit']), 
		['action' => 'edit', $user->id], ['escape' => false, 'title' => 'Editar']) : '' ?>
        <?= !empty($checkUD1) || !empty($checkUD2) ? $this->Form->postLink($this->Html->tag("span", "", ['class'=>'glyphicon glyphicon-remove']), 
		['action' => 'delete', $user->id], ['confirm' => __('Está seguro que desea eliminar a {0}?', $user->full_name), 'escape' => false, 
		'title' => 'Eliminar']) : '' ?>
    </td>
</tr>

Could be that the problem is that the primary key is user_id and group_id and I have to change it to an autonumeric id?

The data seems to be loading fine, from your dump above.

If there are no groups, it correctly generates output showing no groups? If there is one group, it correctly generates output with one group? But if there are multiple groups, it incorrectly generates output showing no groups? Is my understanding of the issue correct?

That’s correct, it shows like there are no groups when there are more than one group

I could solve this issue, the problem was that the primary key for groups_users was user_id and group_id, I put the autonumeric id as the primary key and it solved the issue.