За последние 24 часа нас посетили 21949 программистов и 1098 роботов. Сейчас ищут 709 программистов ...

orWhere expression в Laravel Collections как это в Doctrine

Тема в разделе "Laravel", создана пользователем Awilum, 17 июл 2020.

  1. Awilum

    Awilum Активный пользователь

    С нами с:
    15 ноя 2009
    Сообщения:
    325
    Симпатии:
    26
    Адрес:
    Earth
    Есть ли Laravel Collections аналог вот этого
    https://www.doctrine-project.org/projects/doctrine-collections/en/latest/expressions.html#orwhere
    ?

    пока я понял что надо смотреть в сторону filter() или reject()

    но как их юзать в ТВИГ шаблонах ума не проложу ибо параметром у них это калбек функция

    я могу легко сделать это

    ```
    {{ collect(entries.fetchCollection('movies/drama')).where('title', '=', 'Platforma').title }}
    ```

    но не могу понять добавить условие orWhere в Laravel Collections

    есть идеи?
     
  2. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.825
    Симпатии:
    738
    Адрес:
    Татарстан
    Есть документация по ларке, в том числе по коллекциям... Просто прочитать, 2 минуты

    Цель какая? Выбрать все title коллекции? Так pluck() есть
     
  3. Awilum

    Awilum Активный пользователь

    С нами с:
    15 ноя 2009
    Сообщения:
    325
    Симпатии:
    26
    Адрес:
    Earth
    неделю уже читаю

    вот например такая задача

    fetch all data where brand GT or country USA

    если почему то в ларке нет orWhere как это в доктрине https://www.doctrine-project.org/projects/doctrine-collections/en/latest/expressions.html#orwhere

    то как тогда использовать эти filter() или reject() внутри TWIG шаблонов ?
    --- Добавлено ---
    саму функцию collect() я туда уже передаю

    Код (Text):
    1. <?php
    2.  
    3. declare(strict_types=1);
    4.  
    5. use Twig_Extension;
    6. use Twig_SimpleFunction;
    7. use Twig_Extension_GlobalsInterface;
    8.  
    9. class CollectionTwigExtension extends Twig_Extension
    10. {
    11.     /**
    12.      * Flextype Dependency Container
    13.      */
    14.     private $flextype;
    15.  
    16.     /**
    17.      * Constructor
    18.      */
    19.     public function __construct($flextype)
    20.     {
    21.         $this->flextype = $flextype;
    22.     }
    23.  
    24.     /**
    25.      * Callback for twig.
    26.      *
    27.      * @return array
    28.      */
    29.     public function getFunctions() : array
    30.     {
    31.         return [
    32.             new Twig_SimpleFunction('collect', [$this, 'collect']),
    33.         ];
    34.     }
    35.  
    36.     public function collect($items)
    37.     {
    38.         return collect($items);
    39.     }
    40. }
     
  4. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.076
    Симпатии:
    1.237
    Адрес:
    там-сям
    "в ларке" — это где?
    сравнивать доктрину (хоть ORM, хоть DBAL) с коллекциями как-то странно.
    а если говорить про ларавелевский ORM Eloquent, то в нём есть orWhere().
     
  5. Awilum

    Awilum Активный пользователь

    С нами с:
    15 ноя 2009
    Сообщения:
    325
    Симпатии:
    26
    Адрес:
    Earth
    я же дважды кинул ссылку! ссылку именно на коллекции а не ОРМ
     
  6. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.825
    Симпатии:
    738
    Адрес:
    Татарстан
    collect() - не функция. а структура данных
    чисто теоретически можно в шаблонизаторе в тегах php что то мутить с коллекцией, но зачем?

    правильно предыдущий автор сказал - в Elequent леоайте нормальный запрос отбирая нормально данные... там есть
    Если же хотите именно в коллекции - то используйте filter ... хот имхо - отбор данных должен на уровне слоя БД осуществляться

    фильтр так
    PHP:
    1. $filtered = $collection->filter(function ($item) {
    2.   return ($item->brand =='BMW') ||( $item->country =='USA');
    3. });
     
  7. Awilum

    Awilum Активный пользователь

    С нами с:
    15 ноя 2009
    Сообщения:
    325
    Симпатии:
    26
    Адрес:
    Earth
    вот тут я писал с примерами тоже
    https://laracasts.com/discuss/channels/laravel/orwhere-expression-in-laravel-collections-like-it-is-in-doctrine
    --- Добавлено ---
    какое то странное оправдание, все остальные методы значит можно использовать потому что они есть, а если такого нет как orWhere имено в ларе коллекциях то, все, нельзя никак сразу

    третий раз кидаю на коллекции доктрины этого метода https://www.doctrine-project.org/projects/doctrine-collections/en/latest/expressions.html#orwhere
    --- Добавлено ---
    collect - это функция хелпе которая возвращает мне объект Collection и ни что мне не мешает передать ее внутрь шаблона для работы с данными в шаблоне, работа с коллекцией, c массивом это вполне нормально в шаблоне, я уже и не говорю что некоторые и запросы делают в шаблонах https://docs.craftcms.com/v3/dev/element-queries/
    --- Добавлено ---
    1. $filtered = $collection->filter(function ($item) {
    2. return ($item->brand =='BMW') ||( $item->country =='USA');
    3. });

      ну и как мне это сделать в твиге ? как пропихнуть там в цепочке вызовов методов эту функцию filter c анонимной функцией внутри ?
     
  8. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.825
    Симпатии:
    738
    Адрес:
    Татарстан
    Либо лыжи не едут, либо.....

    При чем тут доктирина?, ты понимаешь Лара - не доктрина и ее коллекции не коллекции доктрины?

    Какие оправдания? Ну нет в коллекция Лары того чего ты хочешь, есть другое (filter) - которое вполне работает,

    Насчет Twig ничего сказать не могу - не юзал
     
  9. Awilum

    Awilum Активный пользователь

    С нами с:
    15 ноя 2009
    Сообщения:
    325
    Симпатии:
    26
    Адрес:
    Earth
    еще раз повторяюсь

    есть разные (либы/классы/проекты/как хотите их называйте ) для работы с коллекциями

    Я долгое время работал с DOCTRINE COLLECTIONS - не ORM, а COLLECTIONS
    хочу перейти на LARAVEL COLLECTIONS, вот обратил внимание на то что в LARAVEL COLLECTIONS НЕТ orWhere() метода как это есть в DOCTRINE COLLECTIONS https://www.doctrine-project.org/projects/doctrine-collections/en/latest/expressions.html#orwhere

    и возник вопрос как тогда мне теперь это делать в LARAVEL COLLECTIONS? с помощью LARAVEL COLLECTIONS filter() ? окей, как мне этот фильтр загнать в цепочке вызовов методов эту функцию filter() у которой анонимная функция внутри ?
     
  10. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.825
    Симпатии:
    738
    Адрес:
    Татарстан
    насколько я понимаю, collect() не родное для twig, а какое-то его расширение?
    Может там посмотреть как и что? Может они такого не предусмотрели?
     
  11. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.076
    Симпатии:
    1.237
    Адрес:
    там-сям
    Да, я был невнимателей, речь шла о коллекциях доктрины. НО , там where/orWhere это методы специального класса Criteria, т.е. есть метод не коллекции, а построителя запросов. А в случае ларавель where это метод коллекции, выдающий сразу новую коллекцию, а не модифицирующий запрос (сравни с QueryBuilder).

    Хотя коллекции Illuminate\Support\Collection можно расширять своими макросами, я думаю, что буквально orWhere реализовать не получится, т.к. наш маркос не сможет работать с исходной коллекцией, но только с уже отфильтрованной первым where().
    --- Добавлено ---
    Реально, filter() выглядит подходящим инструментом. В него можно запихнуть составное условие с И и ИЛИ. Это не будет прямым аналогом построителя запросов, но задачу решает.
     
  12. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.076
    Симпатии:
    1.237
    Адрес:
    там-сям
    Особенно эффектно filter выглядит с новыми стрелочными функциями

    fn($x) => $x['genre'] == 'sci-fi' || $x['genre'] == 'action'

    PHP:
    1. $ php artisan tinker
    2. Psy Shell v0.10.4 (PHP 7.4.8 — cli) by Justin Hileman
    3. >>> $c = collect([['genre'=>'drama', 'title'=>'Gone with the Wind'], ['genre'=>'drama', 'title'=>'Scarlett'], ['genre'=>'sci-fi', 'title'=>'The Rise of Skywalker'], ['genre'=>'action', 'title'=>'Snatch']]);
    4. => Illuminate\Support\Collection {#3063
    5.  all: [
    6.   [
    7.   "genre" => "drama",
    8.   "title" => "Gone with the Wind",
    9.   ],
    10.   [
    11.   "genre" => "drama",
    12.   "title" => "Scarlett",
    13.   ],
    14.   [
    15.   "genre" => "sci-fi",
    16.   "title" => "The Rise of Skywalker",
    17.   ],
    18.   [
    19.   "genre" => "action",
    20.   "title" => "Snatch",
    21.   ],
    22.   ],
    23.   }
    24.  
    25. >>> $c->filter(fn($x) => $x['genre'] == 'sci-fi' || $x['genre'] == 'action');
    26. => Illuminate\Support\Collection {#3044
    27.  all: [
    28.   2 => [
    29.   "genre" => "sci-fi",
    30.   "title" => "The Rise of Skywalker",
    31.   ],
    32.   3 => [
    33.   "genre" => "action",
    34.   "title" => "Snatch",
    35.   ],
    36.   ],
    37.   }
    38. >>>
     
  13. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    @artoodetoo У ТС проблема запихать это дело в твиг.

    Хотя, единственная причина использовать твиг на ларавеле - это давать возможность конечному пользователю модифицировать шаблоны, а тогда такого не должно быть в шаблонах. Да и в принципе, не желательно.
     
  14. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    11.076
    Симпатии:
    1.237
    Адрес:
    там-сям
    согласен. но я отвечал на это: "не могу понять как добавить orWhere в Collection".

    да даже если давать шаблон НЕ конечному пользователю. в шаблон должно заходить что-то готовое, иначе это уже не представление.
    --- Добавлено ---
    если не получается готовое — предоставь простые надстройки, или как это называется в твиг, для извлечения нужных отфильтрованных коллекций. пусть они прячут реализацию внутри. пусть этот fetchByBrandOrCountry() выглядит не сложнее вызова функции.
    ненавижу, блин, эти самостоятельные экосистемы с собственным языком которые перетягивают на себя всё больше и больше кода.
     
  15. Awilum

    Awilum Активный пользователь

    С нами с:
    15 ноя 2009
    Сообщения:
    325
    Симпатии:
    26
    Адрес:
    Earth
    окей, забили на ТВИГ!

    давайте про PHP

    как это, то что я делал в Doctrine Collections
    https://www.doctrine-project.org/projects/doctrine-collections/en/1.6/expressions.html#orwhere

    PHP:
    1. $criteria->where($expr1);
    2. $criteria->andWhere($expr2);
    3. $criteria->orWhere($expr3);
    как абсолютно тоже самое слетать с Laravel Collections ?
    https://laravel.com/docs/7.x/collections

    меня удивляет как логическое AND в Laravel они значит реализовали но вот логического OR там нет! как тогда на Laravel Collections воспроизвести такую же выборку из массива, как это делается в Doctrine Collections ?
     
  16. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    Фильтром. У ларки нету класса "запрос по коллекции", в отличие от доктрины, видимо.

    Подключите к ларке доктрину, и радуйтесь, раз оно вам так удобно :)
     
  17. Awilum

    Awilum Активный пользователь

    С нами с:
    15 ноя 2009
    Сообщения:
    325
    Симпатии:
    26
    Адрес:
    Earth
    я наооборот хочу от доктрины хочу уйти к ларавел коллекциям, потому что там возможностей больше! но меня дико бомбит от отсутсвия логического OR в ларе, тупо затых в одном этом методе orWhere
     
  18. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    А чем filter не угодил, где внутри, в анонимной функции, делаете вообще всё, что хотите..
     
  19. Awilum

    Awilum Активный пользователь

    С нами с:
    15 ноя 2009
    Сообщения:
    325
    Симпатии:
    26
    Адрес:
    Earth
    Да как мне ее присобачить к цепочке вызовов where ?
    --- Добавлено ---
    Можно быть можно filter и приспособить что б он отработал как логическое OR но я хз как
     
  20. Awilum

    Awilum Активный пользователь

    С нами с:
    15 ноя 2009
    Сообщения:
    325
    Симпатии:
    26
    Адрес:
    Earth
    еще один момент!

    как у ларки работа с этим ?

    • Comparison::CONTAINS
    • Comparison::MEMBER_OF
    • Comparison::STARTS_WITH
    • Comparison::ENDS_WITH
    https://www.doctrine-project.org/projects/doctrine-collections/en/1.6/expressions.html#expressions

    я вижу что метод ларки where() понимает таколько такие операторы или я ошибаюсь ?

    https://github.com/laravel/framewor...Support/Traits/EnumeratesValues.php#L924-L935

    и в Ларке можно вытащить также только те данные которые содержат в себе нужный текст как это в Doctrine c Comparison::CONTAINS ?
     
  21. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.555
    Симпатии:
    1.754
    Никак. Не предусмотрели в ларке цепочек where для коллекций, по нормальному (через доп. класс). Не посчитали нужным. Если это очень критично, то выход - либо использовать доктрину, либо попытаться их скрестить, либо найти пакет для ларки, который расширит доступ к коллекциям. Ну или написать самому и выложить такой пакет :)
     
  22. Awilum

    Awilum Активный пользователь

    С нами с:
    15 ноя 2009
    Сообщения:
    325
    Симпатии:
    26
    Адрес:
    Earth