Как сделать фильтр товаров laravel

Добавил пользователь Евгений Кузнецов
Обновлено: 05.10.2024

Я должен следовать красноречивым заявлениям db в моей функции. Два прочитанных заявления на БД.

Сначала я хочу выполнить первый оператор db, а затем хочу выполнить фильтрацию по коллекции / переменной. Вот как это показано ниже. Но получаю ошибку. Что мне нужно изменить?

Non-static method Illuminate\Support\Collection::where() should not be called statically

@ Flamms. Пожалуйста, добавьте также свою ошибку. Чтобы другие могли легко идентифицировать

Многие разработчики, которые используют Laravel, вероятно лишь поверхностно используют фреймворк и в действительности не знают на что, он на самом деле способен. Документация покрывает лишь самые общие моменты использования фреймворка, но не покрывает все его возможности.

Не поймите меня неправимльно, документация хороша, но невозможно в ней покрыть все. Поэтому мы рассмотрим некоторые скрытые недокументированные возможности Laravel.

Каскадные отображения

Доступно с: v4.0.0
Документация: Отсутствует

Файлы отображений могут иметь каскадность, как и файлы конфигурации. Каскадные отображения становятся очень полезными при разработке системы с расширяемыми темами. Рассмотрим следующую структуру папок.

Идея в том, что когда мы выполняем return View::make('theme::blog.index'); то сначала будет осуществлен поиск в директории themes/default/views , если там файл отображения не будет найден, то в app/views .

Чтобы использовать такую возможность нам нужно выполнить View::addNamespace , чтобы зарегистрировать свое собственное пространство имен.

Коллекции

Доступно с: v4.0.0
Документация: Частично

Коллекции являются отличным инструментом для взаимодействия и управления массивами. Коллекции имеют множество удобных методов и реализуют набор полезных интерфейсов, таких как ArrayableInterface , IteratorAggregate , и JsonableInterface .

Допустим мы создаем небольшой движок для блогов, который использует файлы в качестве хранилища. Нам нужна возможность выполнять такие операции как сортировка, фильтрация и пагинация.

Реализация движка блога находится за пределами этой статьи, но представим, что у нас есть массив $acrticles , и каждый элемент массива - это объект класса Article . Все что нам нужно это получить объект класса Collection и передать ему наш массив статей.

Сортировка

Используя коллекции, мы можем сортировать наши статьи. Давайте отсортируем наши статьи и выведем первыми недавно обновленные. Ради этой статьи давайте представим, что при загрузке статей из файловой системы, мы присваиваем свойству updatedAt значение последнего изменения файла.

Методы sortBy и sortByDesc принимают функцию обратного вызова, эта функция должна возвращать значение, которое будет использоваться для сортировки коллекции. В нашем случае, мы можем просто вернуть последнее время обновления статей и отсортировать коллекцию по этому значению.

Фильтрация

По аналогии с сортировкой, мы так же можем использовать коллекции для того чтобы отфильтровать наши статьи, точно так же как, если бы мы использовали выражение WHERE в MySQL. Давайте отфильтруем наши статьи на основе ключевого запроса в поиске.

Метод filter возвращает новый объект класса Illuminate\Support\Collection , так что нужно его присвоить переменной $results . Эта новая коллекция будет содержать только те статьи, у которых в содержании есть строка “Laravel rocks!”.

Пагинация

Используя коллекции, мы можем реализовать пагинацию по нашим статьям, чтобы на одной странице не пришлось выводить слишком много статей за раз.

С помощью метода slice мы получаем часть статей из коллекции и присваиваем ее переменной $results .

В этом примере можно было бы пойти еще дальше и создать новый объект класса Paginator . В этом случае данный объект мог бы сгенерировать для нас все номера страниц и ссылки на них.

Есть еще!

Можно получить случайную статью:

Мы также можем пройтись по нашей коллекции статей, как будто это обычный массив. Это возможно благодаря интерфейсам IteratorAggregate и ArrayIterator .

Мы даже можем преобразовать наши статьи в обычный массив или представить его в виде JSON.

Один из самых интересных методов - groupBy , который позволяет сгруппировать статьи по определенному ключу. Представьте, у каждой статьи есть некоторые мета-данные, которые были спарсены.

Процесс парсинга выходит за рамки этой статьи, мы лишь представим что эти данные хранятся в определенном свойстве объекта Article . Затем можно использовать groupBy , чтобы сгруппировать статьи по категории.

Коллекции являются одной из самых лучших инструментов, которые предоставляет Laravel.

Фильтры по регулярным выражениям.

Доступно с: v4.1.19
Документация: Отсутствует

Фильтрация маршрутов в Laravel это довольно распространенная задача и многие из нас сталкивались с ней в своих проектах. Фильтр позволяет выполнять такие задачи как аутентификация или ограничение по лимиту, как до так и после выполнения запроса к маршруту. Создаются фильтры, используя Route::filter и могут применяться как к индивидуальным маршрутам, так и к группе, с помощью Route::when .

В этом примере мы создадим фильтр restricted , который ожидает один параметр $group . Параметры $route и $request всегда предоставляются до выполнения фильтра.

Но что если нам нужно больше гибкости? Допустим, что нам нужно применить фильтр ко всем маршрутам admin кроме admin/login . Мы можем воспользоваться группой маршрутов и просто оставить маршрут за пределами группы. Или же мы можем воспользоваться Route::whenRegex и написать свое регулярное выражение.

Это регулярное выражение просто отфильтрует все маршруты, которые начинаются с admin , но которые не заканчиваются на /login . Замечательно. Теперь у нас есть наш restricted:admin фильтр, который применяется ко всем маршрутам кроме admin/login .

Доступен с: v4.0.0
Документация: Частичная

Вы без сомнения уже использовали Illuminate\Support\MessageBag , даже не осознавая этого. Самая большая роль MessageBag в том, что он содержит все ваши ошибки валидации,

Переменная $errors , которая доступна в любом файле отображения, является либо пустым объектом MessageBag либо объектом, который был помещен в сессию вместе с Redirect::to('/')->withErrors($validator);

Гораздо, гораздо лучше!

Fluent.

Доступо с: v3.0.0
Документация: Частично

Класс Fluent например используется фреймворком для создания миграций. Между версиями Laravel 3 и Laravel 4 сам класс практически не изменился, единственными значимыми изменениями можно считать лишь несколько новых интерфейсов.

Чтобы воспользоваться классом Fluent , все что нужно это создать его объект.

Теперь у объекта определено 3 атрибута, name со значением Jason , country с Australia и subscriber с булевым true .

До Laravel 4.1 можно было только явно устанавливать и читать атрибуты объекта. С версии Laravel 4.1 можно использовать методы toArray и toJson чтобы получить массив атрибутов или их JSON представление.

В Laravel 4.2 класс также реализует интерфейс JsonSerializable , что означает, что вы можете передать экземпляр непосредственно в json_encode .

Но это еще не все!

Мы рассмотрели лишь небольшую часть возможностей фреймворка Laravel. Но как вы уже наверняка догадались, внутри него, есть еще много интересного.

Лучший способ выяснить, что еще интересного есть внутри Laravel - это заглянуть в его исходный код. Это не так уж страшно, как вы могли бы подумать. Это поможет много понять о работе фреймворка.

Если вы нашли еще какие-либо недокументрированные возможности, не стесняйтесь делиться ими в комментариях.






Допустим у нас есть такой маршрут:

И наш метод show контролера User принимает в качестве id только числовые данные. И чтобы не было ошибки нам нужно делать проверку, что id является числом. Есть несколько вариантов, как это сделать. Не будем на этом останавливаться.

Фильтрация параметра в роуте с помощью регулярного выражения.

Но есть и другой способ, фильтровать параметр id прямо в роуте с помощью регулярного выражения. Для этого у нас есть метод were( , ).

Так, наш роут с проверкой будет такой:

А если нам нужно проверить несколько параметров?

Где id – может быть только числом, а action состоять только из букв. В этом случае наш роут будет выглядеть так:

Т.е. в метод where мы передали массив данных, где ключ – это проверяемый параметр, а значение – это регулярное выражение.

Вот еще один кейс: рассмотрим роут, который описан выше, только id – принимает только числовое значение, а action может принимать только два слова blocked и unblocked.

Тогда наш роут будет следующим:

Создание паттерна фильтрации параметра в роуте.

Для того, чтобы создать паттерн проверки параметра необходимо перейти в app\Providers\RouteServiceProvider.php и в метод boot добавить:

Теперь везде, где есть параметр id он будет проходить проверку. Здорово.

Заключение.

Мы с вами рассмотрели, как фильтровать параметры в роутах с помощью регулярных выражений. Как создать паттерн фильтрации параметра, чтобы не указывать ее в каждом роуте.


Вы узнаете, что такое Ресурсы и как их использовать для API в Laravel-приложениях.

Ресурсы (Resources) — дополнительный слой поверх Eloquent-моделей. Они позволяют поддерживать единый формат возвращаемых данных. Плюс позволяют отсекать лишние или секретные данные, например, пароли и токены.

Настройка проекта

Создадим новый Laravel-проект с пользователями. Откроем миграцию database/migrations/2014_10_12_000000_create_users_table.php и добавим в Schema::create новое поле с возрастом:

Откроем фабрику database/factories/UserFactory.php и также добавим в него поле возраста:

Откроем пользовательскую модель app/Models/User.php и добавим возраст в массив $fillable :

База данных готова. Займемся её наполнением. Открываем database/seeders/DatabaseSeeder.php и раскомментируем (убираем два слэша в начале) следующую строку:

Выполняем посев (наполнение данными):

Получаем 10 фейковых пользователей.

Создание Ресурса

Ресурсы создаются поверх eloquent-моделей. То есть для каждой модели вам нужен отдельный ресурс.

Создадим Ресурс для модели User и посмотрим как его можно использовать для запросов.

Ресурс создается следующей artisan-командой:

Открываем файл UserResource и видим в нём метод toArray . Он используется для возврата данных пользователя. По умолчанию просто возвращается результат этого метода.

Текущая модель, для которой используется Ресурс, представлена внутри класса полем resource . Соответственно, вы можете ссылаться на неё с помощью $this->resource .

Изменим возвращаемый массив, чтобы он возвращал только идентификатор, имя и почту пользователя. Заменим содержимое метода toArray на следующее:

Готово, мы создали наш первый Ресурс!

Создаем конечную точку API

Создадим эндпоинт, который позволит получать данные любого пользователя по его идентификатору. Но сначала создадим контроллер:

Сначала он проверяет, существует ли пользователь с таким идентификатором. Если нет, то возвращаем json с ошибкой. Если существует, то возвращаем экземпляр UserResource .

Обратите внимание, что для создания экземпляра Ресурса вам необходимо передать ему модель. Например так:

Это все! Осталось добавить конечную точку в маршруты.

Открываем routes/api.php и добавляем:

Наш API готов. Пора его проверить.

Для тестирования API удобнее использовать что-то вроде Postman или Thunder Client. Но пока нам нужен обычнй GET-запрос без авторизации, то просто откроем адрес в браузере: localhost:8000/api/user/1

Видим, что нам пришёл json с двумя ключами success и user . Обратите внимание что объект user содержит только id , name и email , то есть именно те поля, которые мы настроили в нашем Ресурсе


.

Вы можете попробовать менять идентификатор и увидите, что API придерживается единой структуры ответа для всех пользователей.

Ресурс коллекции пользователей

Ресурсы предназначены не только для экземпляров моделей. Вы можете создать ресурс коллекции, который принимает в качестве параметра коллекции экземпляров моделей и, при необходимости, изменяет её.

Чтобы создать Ресурс коллекции для модели User выполним следующую команду:

Обратите внимание, что для Ресурсов коллекций существует соглашение об именах Collection , которое гарантирует, что коллекция связана с правильной моделью.

Итак, поскольку название модели — User , то название Ресурса коллекции будет UserCollection . Если хотите назвать коллекцию по другому, то можете указать класс ресурса, используя поле $collects в классе коллекции.

Ресурсы коллекций аналогичны обычным Ресурсам. Также есть метод toArray , который используется для задания структуры коллекций.

Изменим его содержание на следующее:

Обратите внимание, что $this->collection вернет массив объектов со структурой, аналогичной заданной в UserResource , для каждого пользователя в коллекции.

Создаем конечную точку API

Создадим эндпоинт, которая позволит нам получить всех пользователей. Добавим в UserController следующий метод:

Для создания экземпляр ресурса коллекции также необходимо передать коллекцию моделей в качестве параметра.

Добавим новый маршрут в routes/api.php :

Давайте его проверим. Открываем адрес localhost:8000/api/user в браузере. Он вернет два ключа success и users , который содержит массив всех пользователей и все они будут иметь структуру, заданную наши в UserResource .


Это пример того, как заданный Ресурс гарантирует одинаковую структуру для всех запросов.

Условные поля

Иногда, в зависимости от условий, вам нужно будет добавить дополнительное поле в ответ. Для этого можно использовать метод when .

Предположим, что нам нужно возвращать возраст пользователя, если ему больше 18 лет. Добавим следующую строку в возвращаемый массив toArray в UserResource :

Теперь, если пользователь старше 18 лет, то в ответ будет добавлено полей age . Обратите внимание, что первый параметр это условие, а второй — ожидаемое значение.

Откроем адрес localhost:8000/api/user в браузере. Теперь у взрослых пользователей будет поле возраста, а у детей — нет.


Обратите внимание, что в вашем случае результат будет другой, так как фабрика генерирует пользователей случайным образом.

Заключение

Ресурсы позволяют структурировать данные выдаваемых в запросах и гарантировать сокрытие небезопасных данных.

Читайте также: