对分页进行排序,例如 CakePHP 中的行别名计数 3.x,数据通过链接连接 table
Sort Pagination by, row Alias Count for example in CakePHP 3.x, data by linking a join table
正如我在 cakephp 中所做的那样 3.x 我可以按具有计数的行对结果进行排序,因为我看不到表格,这在 CakePHP [=34= 中非常相似] 工作没有问题。
缺少什么才能在 CakePHP 3.x 中做同样的事情......?
我的测试是 PHP 7.1 WAMP
中的 en CakePHP v3.3.10
除了最后的 count_users 之外,所有的分页排序都正确,当我点击它时没有给出错误,只是不对数据进行排序。
HTML ctp
<?= $this->Paginator->sort('count_users',_('N° Users')); ?>
控制器
$this->Licensees->schema()
->addColumn('count_users', [
'type' => 'integer',
]);
$this->Licensees->aliasField('count_users');
$where = [
'recursive'=>-1,
'fields' => [
'Licensees.id',
'Licensees.name',
'Licensees.created',
'Licensees.modified',
'Licensees__count_users' => 'count(LicenseesUsers.licensees_id)',
// 'count_users' => 'count(LicenseesUsers.licensees_id)',
// 'Licensees.count_users' => 'count(LicenseesUsers.licensees_id)',
],
'sortWhitelist' => ['name','count_users','created','modified'],
'join' => [
'LicenseesUsers' => [
'table' => 'licensees_users',
'type' => 'LEFT',
'conditions' => [
'LicenseesUsers.licensees_id = Licensees.id'
],
],
],
'group' => 'Licensees.id'
];
// Set pagination
$this->paginate = $where;
// Get data
$licensees = $this->paginate($this->Licensees);
显示错误排序分页字段count_users
object(Cake\ORM\Query) {
'(help)' => 'This is a Query object, to get the results execute or iterate it.',
'sql' => 'SELECT Licensees.id AS `Licensees__id`, Licensees.name AS `Licensees__name`, Licensees.created AS `Licensees__created`, Licensees.modified AS `Licensees__modified`, count(LicenseesUsers.licensees_id) AS `Licensees__count_users`, count(LicenseesUsers.licensees_id) AS `count_users` FROM licensees Licensees LEFT JOIN licensees_users LicenseesUsers ON LicenseesUsers.licensees_id = Licensees.id LEFT JOIN users Users ON Users.id = LicenseesUsers.users_id GROUP BY Licensees.id ORDER BY Licensees.count_users asc LIMIT 50 OFFSET 0',
'params' => [],
'defaultTypes' => [
'Licensees__id' => 'uuid',
'Licensees.id' => 'uuid',
'id' => 'uuid',
'Licensees__name' => 'string',
'Licensees.name' => 'string',
'name' => 'string',
'Licensees__active' => 'boolean',
'Licensees.active' => 'boolean',
'active' => 'boolean',
'Licensees__deleted_at' => 'datetime',
'Licensees.deleted_at' => 'datetime',
'deleted_at' => 'datetime',
'Licensees__created' => 'datetime',
'Licensees.created' => 'datetime',
'created' => 'datetime',
'Licensees__modified' => 'datetime',
'Licensees.modified' => 'datetime',
'modified' => 'datetime',
'Licensees__count_users' => 'integer',
'Licensees.count_users' => 'integer',
'count_users' => 'integer'
],
'decorators' => (int) 0,
'executed' => false,
'hydrate' => true,
'buffered' => true,
'formatters' => (int) 0,
'mapReducers' => (int) 0,
'contain' => [],
'matching' => [],
'extraOptions' => [
'recursive' => (int) -1,
'scope' => null,
'sortWhitelist' => [
(int) 0 => 'name',
(int) 1 => 'count_users',
(int) 2 => 'created',
(int) 3 => 'modified'
],
'whitelist' => [
(int) 0 => 'limit',
(int) 1 => 'sort',
(int) 2 => 'page',
(int) 3 => 'direction'
]
],
'repository' => object(App\Model\Table\LicenseesTable) {
'registryAlias' => 'Licensees',
'table' => 'licensees',
'alias' => 'Licensees',
'entityClass' => 'App\Model\Entity\Licensee',
'associations' => [
[maximum depth reached]
],
'behaviors' => [
[maximum depth reached]
],
'defaultConnection' => 'default',
'connectionName' => 'default'
}
}
如评论中所述,您必须使用 count_users
变体,即没有任何别名,这通常可以正常工作。
因为您已将 count_users
列作为架构的一部分 ($this->Licensees->schema()->addColumn()
),所以事情会发生变化,这将导致 CakePHP 将其视为真正的列,因此它将列名的内部别名,这将导致 ORDER BY
子句使用 Licensees.count_users
,这将不起作用,因为不存在这样的列(您不能将计算列添加到现有别名)。
如果您需要将计算列视为特定类型,则修改 (select) 类型映射,方法是创建和分页适当的查询对象,或修改查询例如飞入取景器,或通过 Model.beforeFind
事件。
// use getSelectTypeMap() as of CakePHP 3.4
$query->selectTypeMap()->addDefaults([
'count_users' => 'integer'
]);
另见
- API > \Cake\Database\Query::selectTypeMap()
- API > \Cake\Database\TypeMap
- Cookbook > Controllers > Pagination
- Cookbook > ORM > Retrieving Data & Results Sets > Custom Finder Methods
- Cookbook > ORM > Table Objects > Lifecycle Callbacks > beforeFind
- Cakephp-3.x: How to change the data type of a selected alias?
谢谢ndm,就是你说的。
该问题将在以下行中进行注释。
控制器:
// $this->Licensees->schema()
// ->addColumn('count_users', [
// 'type' => 'integer',
// ]);
// $this->Licensees->aliasField('count_users');
$where = [
'recursive'=>-1,
'fields' => [
'Licensees.id',
'Licensees.name',
'Licensees.created',
'Licensees.modified',
// 'Licensees__count_users' => 'count(LicenseesUsers.licensees_id)',
'count_users' => 'count(LicenseesUsers.licensees_id)',
],
'sortWhitelist' => ['name','count_users','created','modified'],
'join' => [
'LicenseesUsers' => [
'table' => 'licensees_users',
'type' => 'LEFT',
'conditions' => [
'LicenseesUsers.licensees_id = Licensees.id'
],
],
],
'group' => 'Licensees.id'
];
// Set pagination
$this->paginate = $where;
// Get data
$licensees = $this->paginate($this->Licensees);
正如我在 cakephp 中所做的那样 3.x 我可以按具有计数的行对结果进行排序,因为我看不到表格,这在 CakePHP [=34= 中非常相似] 工作没有问题。 缺少什么才能在 CakePHP 3.x 中做同样的事情......? 我的测试是 PHP 7.1 WAMP
中的 en CakePHP v3.3.10除了最后的 count_users 之外,所有的分页排序都正确,当我点击它时没有给出错误,只是不对数据进行排序。
HTML ctp
<?= $this->Paginator->sort('count_users',_('N° Users')); ?>
控制器
$this->Licensees->schema()
->addColumn('count_users', [
'type' => 'integer',
]);
$this->Licensees->aliasField('count_users');
$where = [
'recursive'=>-1,
'fields' => [
'Licensees.id',
'Licensees.name',
'Licensees.created',
'Licensees.modified',
'Licensees__count_users' => 'count(LicenseesUsers.licensees_id)',
// 'count_users' => 'count(LicenseesUsers.licensees_id)',
// 'Licensees.count_users' => 'count(LicenseesUsers.licensees_id)',
],
'sortWhitelist' => ['name','count_users','created','modified'],
'join' => [
'LicenseesUsers' => [
'table' => 'licensees_users',
'type' => 'LEFT',
'conditions' => [
'LicenseesUsers.licensees_id = Licensees.id'
],
],
],
'group' => 'Licensees.id'
];
// Set pagination
$this->paginate = $where;
// Get data
$licensees = $this->paginate($this->Licensees);
显示错误排序分页字段count_users
object(Cake\ORM\Query) {
'(help)' => 'This is a Query object, to get the results execute or iterate it.',
'sql' => 'SELECT Licensees.id AS `Licensees__id`, Licensees.name AS `Licensees__name`, Licensees.created AS `Licensees__created`, Licensees.modified AS `Licensees__modified`, count(LicenseesUsers.licensees_id) AS `Licensees__count_users`, count(LicenseesUsers.licensees_id) AS `count_users` FROM licensees Licensees LEFT JOIN licensees_users LicenseesUsers ON LicenseesUsers.licensees_id = Licensees.id LEFT JOIN users Users ON Users.id = LicenseesUsers.users_id GROUP BY Licensees.id ORDER BY Licensees.count_users asc LIMIT 50 OFFSET 0',
'params' => [],
'defaultTypes' => [
'Licensees__id' => 'uuid',
'Licensees.id' => 'uuid',
'id' => 'uuid',
'Licensees__name' => 'string',
'Licensees.name' => 'string',
'name' => 'string',
'Licensees__active' => 'boolean',
'Licensees.active' => 'boolean',
'active' => 'boolean',
'Licensees__deleted_at' => 'datetime',
'Licensees.deleted_at' => 'datetime',
'deleted_at' => 'datetime',
'Licensees__created' => 'datetime',
'Licensees.created' => 'datetime',
'created' => 'datetime',
'Licensees__modified' => 'datetime',
'Licensees.modified' => 'datetime',
'modified' => 'datetime',
'Licensees__count_users' => 'integer',
'Licensees.count_users' => 'integer',
'count_users' => 'integer'
],
'decorators' => (int) 0,
'executed' => false,
'hydrate' => true,
'buffered' => true,
'formatters' => (int) 0,
'mapReducers' => (int) 0,
'contain' => [],
'matching' => [],
'extraOptions' => [
'recursive' => (int) -1,
'scope' => null,
'sortWhitelist' => [
(int) 0 => 'name',
(int) 1 => 'count_users',
(int) 2 => 'created',
(int) 3 => 'modified'
],
'whitelist' => [
(int) 0 => 'limit',
(int) 1 => 'sort',
(int) 2 => 'page',
(int) 3 => 'direction'
]
],
'repository' => object(App\Model\Table\LicenseesTable) {
'registryAlias' => 'Licensees',
'table' => 'licensees',
'alias' => 'Licensees',
'entityClass' => 'App\Model\Entity\Licensee',
'associations' => [
[maximum depth reached]
],
'behaviors' => [
[maximum depth reached]
],
'defaultConnection' => 'default',
'connectionName' => 'default'
}
}
如评论中所述,您必须使用 count_users
变体,即没有任何别名,这通常可以正常工作。
因为您已将 count_users
列作为架构的一部分 ($this->Licensees->schema()->addColumn()
),所以事情会发生变化,这将导致 CakePHP 将其视为真正的列,因此它将列名的内部别名,这将导致 ORDER BY
子句使用 Licensees.count_users
,这将不起作用,因为不存在这样的列(您不能将计算列添加到现有别名)。
如果您需要将计算列视为特定类型,则修改 (select) 类型映射,方法是创建和分页适当的查询对象,或修改查询例如飞入取景器,或通过 Model.beforeFind
事件。
// use getSelectTypeMap() as of CakePHP 3.4
$query->selectTypeMap()->addDefaults([
'count_users' => 'integer'
]);
另见
- API > \Cake\Database\Query::selectTypeMap()
- API > \Cake\Database\TypeMap
- Cookbook > Controllers > Pagination
- Cookbook > ORM > Retrieving Data & Results Sets > Custom Finder Methods
- Cookbook > ORM > Table Objects > Lifecycle Callbacks > beforeFind
- Cakephp-3.x: How to change the data type of a selected alias?
谢谢ndm,就是你说的。
该问题将在以下行中进行注释。
控制器:
// $this->Licensees->schema()
// ->addColumn('count_users', [
// 'type' => 'integer',
// ]);
// $this->Licensees->aliasField('count_users');
$where = [
'recursive'=>-1,
'fields' => [
'Licensees.id',
'Licensees.name',
'Licensees.created',
'Licensees.modified',
// 'Licensees__count_users' => 'count(LicenseesUsers.licensees_id)',
'count_users' => 'count(LicenseesUsers.licensees_id)',
],
'sortWhitelist' => ['name','count_users','created','modified'],
'join' => [
'LicenseesUsers' => [
'table' => 'licensees_users',
'type' => 'LEFT',
'conditions' => [
'LicenseesUsers.licensees_id = Licensees.id'
],
],
],
'group' => 'Licensees.id'
];
// Set pagination
$this->paginate = $where;
// Get data
$licensees = $this->paginate($this->Licensees);