Как фильтровать объекты на основе места рабочего процесса Symfony, которое является массивом?

#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 вместо массива, и это работает. Я отредактирую свой пост, чтобы помочь другим, если кто-то будет бороться так же, как я …