2016-02-19 4 views
0

Когда im пытается передать условие подходящей функции, сопоставляя задачи с проектами, paginator передает ORDER BY, удаляя объект Table и заставляя столбец быть неоднозначным.CakePHP 3 paginate order by ambigious column bug?

Это ошибка или кто-нибудь знает, как это могло случиться?

MATCHING

if($groupFilter) 
{ 
    // Filtering by group 
    $projects = $this->Projects->find('all')->where($wheres) 
     ->matching('Tasks', function ($q) use ($groupFilter) { 
      return $q->where(['Tasks.group_id' => $groupFilter, 'Tasks.removed' => 0])->order(['Tasks.deadline ASC', 'Tasks.created ASC']); 
       }) 
     ->contain(['Customers','Tasks.Users'])->distinct(['Projects.id']); 
} 
else 
{ 
    // Groupfiltering is not set, filter normally. 
    $projects = $this->Projects->find('all')->contain(['Customers'])->where($wheres)->contain([ 
     'Tasks', 
     'Tasks.Users' 
    ]); 
} 

постраничной

$this->paginate = [ 
    'sortWhitelist' => [ 
      'Projects.name', 'Customers.name', 'Projects.deadline IS NULL', 'Projects.tasks_active', 'Projects.tasks_used_hours', 'Projects.deadline' 
    ], 
    'order' => [ 
     'Projects.deadline IS NULL' => 'ASC', 
     'Projects.deadline' => 'ASC' 
    ], 
    'limit' => 50 
]; 
$this->set('projects', $this->paginate($projects)); 

SQL

SELECT projects.id      AS `Projects__id`, 
     projects.customer_id    AS `Projects__customer_id`, 
     projects.user_id     AS `Projects__user_id`, 
     projects.name      AS `Projects__name`, 
     projects.description    AS `Projects__description`, 
     projects.deadline     AS `Projects__deadline`, 
     projects.status     AS `Projects__status`, 
     projects.tasks_total    AS `Projects__tasks_total`, 
     projects.tasks_active    AS `Projects__tasks_active`, 
     projects.tasks_completed   AS `Projects__tasks_completed`, 
     projects.tasks_allocated_hours  AS `Projects__tasks_allocated_hours`, 
     projects.tasks_used_hours   AS `Projects__tasks_used_hours`, 
     projects.tasks_used_hours_nondebit AS 
     `Projects__tasks_used_hours_nondebit`, 
     projects.created     AS `Projects__created`, 
     tasks.id       AS `Tasks__id`, 
     tasks.create_user_id    AS `Tasks__create_user_id`, 
     tasks.responsible_user_id   AS `Tasks__responsible_user_id`, 
     tasks.user_id      AS `Tasks__user_id`, 
     tasks.customer_id     AS `Tasks__customer_id`, 
     tasks.task_type_id     AS `Tasks__task_type_id`, 
     tasks.group_id      AS `Tasks__group_id`, 
     tasks.hour_bank_id     AS `Tasks__hour_bank_id`, 
     tasks.contact_person_id   AS `Tasks__contact_person_id`, 
     tasks.helpdesk_task_id    AS `Tasks__helpdesk_task_id`, 
     tasks.name       AS `Tasks__name`, 
     tasks.description     AS `Tasks__description`, 
     tasks.amount      AS `Tasks__amount`, 
     tasks.report_sum     AS `Tasks__report_sum`, 
     tasks.amount_type     AS `Tasks__amount_type`, 
     tasks.status      AS `Tasks__status`, 
     tasks.invoice      AS `Tasks__invoice`, 
     tasks.invoiced      AS `Tasks__invoiced`, 
     tasks.created      AS `Tasks__created`, 
     tasks.deadline      AS `Tasks__deadline`, 
     tasks.project_id     AS `Tasks__project_id`, 
     tasks.start      AS `Tasks__start`, 
     tasks.prioritized     AS `Tasks__prioritized`, 
     tasks.completed_at     AS `Tasks__completed_at`, 
     tasks.removed      AS `Tasks__removed`, 
     customers.id      AS `Customers__id`, 
     customers.name      AS `Customers__name`, 
     customers.api      AS `Customers__api` 
FROM projects Projects 
     INNER JOIN tasks Tasks 
       ON (tasks.group_id = :c0 
        AND tasks.removed = :c1 
        AND projects.id = (tasks.project_id)) 
     LEFT JOIN customers Customers 
       ON customers.id = (projects.customer_id) 
WHERE projects.status = :c2 
GROUP BY projects.id 
ORDER BY deadline IS NULL ASC, // missing table 
      projects.deadline ASC 
LIMIT 50 offset 0 

ответ

1

Такие ключи порядка не supporte d, механизм префиксации paginators наткнется на него, так как он ожидает синтаксис Alias.field, и существование полей будет проверено на схеме модели.

https://github.com/cakephp/.../3.2.2/src/Controller/Component/PaginatorComponent.php#L345

Для того, чтобы иметь возможность использовать такие пункты заказа, вы должны будете применять их с помощью объекта запроса вместо. Следовательно, вы не можете сортировать пользователя по такой статье из коробки, вам нужно будет реализовать механизм, который захватывает (и выводит) значение sort из запроса запроса и применяет его к запросу, например

$sort = $this->request->query('sort'); 
// you may want to choose a non-technical alias instead 
if ($sort !== null && $sort === 'Projects.deadline IS NULL') { 
    unset($this->request->query['sort']); 

    $expression = $projects->newExpr()->isNull('Projects.deadline'); 
    if (strtoupper($this->request->query('direction')) === 'ASC') { 
     $projects->orderAsc($expression); 
    } else { 
     $projects->orderDesc($expression); 
    } 
} 
Смежные вопросы