Постановка задачи: требуется составить Criteria для Propel, который позволяет выполнить запрос с использованием CASE WHEN и при этом не потерять выбираемые колонки и гидрацию объектов.
Собственно казалось бы, используем конструкцию $criteria->addAsColumn(…) и все. Но не тут то было, при использовании этого запроса теряются все колонки, выбираемые по-умолчанию Propel’ом.
Итак, вот, пример запроса который нам нужно выполнить:
SELECT
`table`.`id`,
`table`.`field1`,
`table`.`field2`,
CASE
WHEN
`table`.`photo_count` > 0
THEN 1
WHEN
`table`.`photo_count` = 0
THEN 0
END as has_photo
FROM
`table`
WHERE
`table`.`status_id` = 2
AND
`table`.`type_id` = 1
...
ORDER BY
has_photo DESC,
`table`.`created_at` DESC
Ключевые особенности – дополнительное “поле” photo_count принимает значение 0 или 1 и по нему осуществляется сортировка. При этом на выходе мы хотим получить Propel-объекты.
На самом деле решение очень простое:
PropertyPeer::addSelectColumns( $criteria );
$criteria->addAsColumn(
"has_photo" ,
"CASE WHEN " . TablePeer::PHOTO_COUNT . " > 0 THEN 1 " .
"WHEN " . TablePeer::PHOTO_COUNT . " = 0 THEN 0 END"
);
$criteria->addDescendingOrderByColumn( "has_photo" );
Ключевой особенностью этого решения является первая строка. Просто, не так ли? Тем не менее чтобы найти решение проблемы потребовался не один час, куча нервов. Собственно ответ был найден в trac’е propel – http://propel.phpdb.org/trac/ticket/643
с уважением, отдел по борьбе с propel )))