Сортировка нумерации страниц по числу псевдонимов строк, например, в CakePHP 3.x, данные путем связывания таблицы соединений

Как я могу в CakePHP 3.x, я могу отсортировать результаты по строке, которая имеет счетчик, потому что я не вижу формы, что-то очень похожее в CakePHP 2.x работает без проблем. Чего не хватает, чтобы сделать то же самое в CakePHP 3.x..? Мой тест - en CakePHP v3.3.10 в PHP 7.1 WAMP

Все виды разбиения на страницы работают правильно, за исключением последнего 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'

    }

}

2 ответа

Решение

Как уже упоминалось в комментариях, вы должны использовать 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'
]);

Смотрите также

Спасибо, это было то, что вы сказали.

Проблема будет прокомментирована в следующих строках.

контроллер:

//    $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);
Другие вопросы по тегам