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
.
另见
我正在使用 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
.
另见