#symfony #api-platform.com
Вопрос:
Я некоторое время боролся с этим, но не могу найти чистый способ сделать это, поэтому я ищу помощи.
У меня есть пользовательские фильтры (ApiPlatform 2.5 и Symfony 5.1) для выходных данных API базы данных, и мне нужно фильтровать по текущему месту рабочего процесса или статусу, как вам нравится, каждого вывода.
Статус имеет нижеприведенную структуру, которая является местом рабочего процесса symfony :
Status = { "OPEN": 1 }
Моя проблема в том, что статус хранится в базе данных в виде массива, и я не могу найти способ, чтобы конструктор запросов нашел совпадение.
Я попытался локально построить массив , чтобы сделать=, ПОДОБНОЕ или В :
$status['OPEN'] = 1; $queryBuilder-gt;andWhere(sprintf('%s.Status = :st', $rootAlias)) -gt;leftJoin(sprintf('%s.Objs', $rootAlias), 'o') -gt;andWhere('o.Profile = :p') -gt;setParameters(array( 'st' =gt; $status, 'p' =gt; $profile ));
Но ни в коем случае 🙁
Я реализовал обходной путь, который работает, но мне это не нравится, так как я часто использую рабочие процессы и мне нужен чистый способ фильтрации выходных данных. Мой обходной путь довольно прост: когда статус записывается в БД в виде массива, я также сохраняю его в виде строки в другом поле, называемом statusText, тогда фильтрация по statusText проста и понятна.
Очевидно, что статус может иметь различное содержание : ОТКРЫТО, ЗАКРЫТО, ЗАКРЫТО,…
Помощь оценена по достоинству !! Спасибо
РЕДАКТИРОВАНИЕ и решение
Как предложил Юсеф, используйте scienta/doctrine-json-функции и используйте JSON_EXTRACT :
композитору требуются научные/доктринальные-json-функции
Важно, что это было частью моей проблемы, используйте тип доктрины json_array массив not для хранения статуса или состояния, как бы вы его ни называли, в базе данных.
Интегрируйте псевдоним, предоставленный в пользовательском фильтре ApiPlatform :
$rootAlias = $queryBuilder-gt;getRootAliases()[0]; $json_extract_string = "JSON_EXTRACT(".$rootAlias.".Status, '$.OPEN') = 1"; $queryBuilder-gt;andwhere($json_extract_string ) -gt;leftJoin(sprintf('%s.Objs', $rootAlias), 'o') -gt;andWhere('o.Profile = :p') -gt;setParameter('p', $profile);
Ответ №1:
Вам нужно спросить Доктрину, содержит ли массив JSON статус, но вы не можете сделать это с помощью метода QueryBuilder. При попадании в ограничения ORM вы можете использовать собственный запрос с сопоставлением результатов. Это позволяет вам написать чистый SQL-запрос, используя специфические функции вашей СУБД, но при этом получать объекты сущностей. Или вы можете использовать scienta/doctrine-json-функции и использовать JSON_EXTRACT
Комментарии:
1. Спасибо за ваш ответ, я попробовал пакет, но столкнулся с ошибкой : 3141 Неверный текст JSON в аргументе 1 для функции json_extract . Аргумент 1-это массив состояния из БД, который является буквальным в БД : a:1:{s:4:»ОТКРЫТО»;i:1;} так что, возможно, синтаксический анализатор отклоняет его как не JSON no ?
2. хорошо, в этом и была проблема, я изменил тип ORM var на json_array вместо массива, и это работает. Я отредактирую свой пост, чтобы помочь другим, если кто-то будет бороться так же, как я …