CakePHP 列表查找器方法未按预期返回数组

CakePHP list finder method not returning array as expected

我正在使用 Cake 的 $table->find('list') 查找器方法来检索一组关联用户 [id => name]。过去使用过它并且效果很好。在此查找中,我包含一个 belongsToMany table 并检索 [id => name].

\App\Model\Table\SitesTable::initialize 中定义了 ClientUsersWithAuthorities belongsToMany 关系

$this->belongsToMany('ClientUsersWithAuthorities', [
  'className'        => 'AppUsers',
  'joinTable'        => 'sites_client_users',
  'foreignKey'       => 'site_id',
  'targetForeignKey' => 'user_id',
  'propertyName'     => 'client_users_with_authorities']);

\App\Controller\ClientGroupsController::getClientgroupUsers

$siteClientUsers = $this->Sites->find('list', [
  'keyField'   => 'client_users_with_authorities.id',
  'valueField' => 'client_users_with_authorities.full_name'])
->where(['id' => $siteId])
->contain(['ClientUsersWithAuthorities'])
->toArray();

$siteClientUsers returns [0 => null] 而不是预期的 [1234 => 'Client 1 name', 5678 => 'Client 2 name']。两个用户都存在于联接 table.

其他三种方法(下方)return 我正在寻找的数组,我希望 $this->Sites->find('list') 生成它。 该食谱描述了可以列出的关联数据。 https://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html#finding-key-value-pairs

那么为什么 $this->Sites->find('list') 没有生成预期的数组?

mapReduce

$mapper = function ($data, $key, $mapReduce) {
if (!empty($data['client_users_with_authorities'])) {
    foreach ($data['client_users_with_authorities'] as $user) {
        $mapReduce->emit($user);
    }}};
$siteClientUsers = $this->Sites->find('list', [
    'keyField'   => 'id',
    'valueField' => 'full_name'])
->where(['id' => $siteId])
->contain(['ClientUsersWithAuthorities'])
->mapReduce($mapper)
->toArray();

哈希::组合

$siteClientUsers = $this->Sites->find('all')
->where(['id' => $siteId])
->contain(['ClientUsersWithAuthorities'])
->toArray();
$siteClientUsers  = Hash::combine($siteClientUsers,'{n}.client_users_with_authorities.{n}.id', '{n}.client_users_with_authorities.{n}.full_name');

Temp belongsTo 加入关系 table

$table = $this->getTableLocator()->get('SitesClientUsers');
$table->belongsTo('Users', [
'className'   => 'AppUsers',
'foreign_key' => 'user_id']);
$siteClientUsers =  $table->find('list', [
    'keyField' => 'Users.id',
    'valueField' => 'Users.full_name'
])
->select(['Users.id', 'Users.full_name'])
->where(['SitesClientUsers.site_id' => $siteId])
->contain(['Users'])
->toArray();

食谱说:

You can also create list data from associations that can be reached with joins

重要的部分是“可以通过联接达到”,belongsToMany 关联则不是这样。考虑到列表转换发生在 PHP 级别,描述可能应该专注于此,但它仍然有点有效。

client_users_with_authorities 将是一个数组,即可能有多个记录,因此您不能使用它来填充父记录 - 一个 Sites 记录代表一个列表条目。如果你想找到属于特定站点的 ClientUsersWithAuthorities 列表,那么你可以使用你的其他解决方案之一(或类似的东西),或者你可以例如从另一边查询关联并在 Sites:

上使用匹配器
$query = $this->Sites->ClientUsersWithAuthorities
    ->find('list', [
        'keyField' => 'id',
        'valueField' => 'full_name'
    ])
    ->matching('Sites', function (\Cake\ORM\Query $query) use ($siteId) {
        return $query->where([
            'Sites.id' => $siteId
        ]);
    })
    ->group('ClientUsersWithAuthorities.id');

这将创建基于 Sites.id 的联接,因此您只会检索与 Sites 关联的 ClientUsersWithAuthorities,其中 Sites.id 匹配 $siteId.

另见