Новая функция моего Doctrine-приложения позволяет пользователю добавлять документы и обновлять документы с более новыми версиями.
Document <-1--m-> DocumentVersion
Пользователь может установить диапазон дат, когда версия документа будет действительной.Таким образом, версия документа действительна, если
- это самая новая версия
- , она находится в допустимом диапазоне дат, если установлено
У объекта есть getInvalid()
метод, который позволяет проверить это в представлении позже.Чтобы установить поле, я написал запрос MySQL:
SELECT
IF(
(dv.valid_begin IS NULL OR (NOW() >= dv.valid_begin)) AND
(dv.valid_end IS NULL OR(NOW() <= dv.valid_end))
AND MAX(dv2.value) = dv.value
, 0, 1) AS invalid,
d.id, dv.id AS document_version_id,
MAX(dv2.value) AS current_version,
dv.valid_begin, dv.valid_end
FROM document d
INNER JOIN document_version dv ON dv.document_id = d.id
INNER JOIN document_version dv2 ON dv2.document_id = d.id
GROUP BY d.id, dv.id
Запрос сложный и использует второе вспомогательное соединение (dv2
), которое позволяет определить текущую версию.Он заполняет столбец invalid
, как и ожидалось для моих тестовых данных:
![query result](https://i.stack.imgur.com/JmgYd.png)
Мне удалось адаптировать запрос Doctrine, но я не могу найтиспособ записи значения столбца invalid
в соответствующее поле сущности:
$repo = $this->getDoctrine()->getRepository('AppBundle:Document');
$qb = $repo->createQueryBuilder('d')->select('d');
$qb->innerJoin('d.documentVersion', 'v');
$qb->innerJoin('d.documentVersion', 'v_temp');
$qb->addSelect('v', 'CASE WHEN
MAX(v_temp.value) = v.value AND
(v.valid_begin IS NULL OR (NOW() >= v.valid_begin)) AND
(v.valid_end IS NULL OR (NOW() <= v.valid_end))
THEN 0 ELSE 1 END AS invalid
');
$qb->groupBy('d.id, v.id');
Doctrine записывает invalid
в результат запроса отдельно.Это значение больше не имеет смысла, так как нам понадобится значение для каждой версии документа, но вместо этого у нас будет одно значение для всех версий документа:
![Doctrine's query result](https://i.stack.imgur.com/9tXmM.png)
ДаЯ знаю - это правильное поведение, описанное в документации Доктрины.Но мне интересно, действительно ли нет способа правильно отобразить вычисленное значение.Может быть, написание специального гидратора?