/ laravel

Как кастомизировать имя параметра пагинации Laravel

Очень часто мне приходится создавать API для других команд разработчиков. И одной из самых распространённых задач является постраничное отображение данных. Благодаря таким задачам, я узнал много о пагинации в Laravel: как переопределить ключ page на кастомный, или даже как указать конкретную страницу для отображения.

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

Order::paginate(5);

Этот код возвращает нам 5 записей, и дополнительные метаданные о количестве записей, страниц, ссылки.
-----------------2020-09-05-16-57-17

Очень часто нам приходится отправлять эти метаданные на фронтенд. И если подробнее изучить структуру ответа пагинатора, то заметим, что параметр next_page_url указывает на следующую страницу результатов выборки. А информация о номере страницы задаётся параметром page.

И этого функционала достаточно для любого стандартного проекта. Однако, бывают случаи, когда нам всё-таки нужно переопределить параметр page в пагинаторе на свой собственный. Например, когда на одной странице добавлено несколько пагинаций. Потому что при переходе на следующую страницу одного пагинатора, это влияло бы и на второй.

Как изменить параметр запроса "page"

Есть два способа, чтобы сделать это:

  • Передать кастомное имя в метод paginate.
  • Использовать метод пагинатора setPageName.

Способ 1

Передадим кастомное имя параметра в метод paginate. Да, многие не знают, но метод paginate принимает 4 аргумента:

  1. Количество записей на страницу (limit).
  2. Поля таблицы для возврата.
  3. Ключ номера страницы (по умолчанию, page). Это то, что нас интересует.
  4. Номер страницы пагинации. Можно задать номер страницы вручную, однако, достаточно просто переопределить ключ, и номер страницы будет считан автоматически по ключу из запроса.

В текущем варианте, параметры по-умолчанию выглядят так:

Order::paginate(5, ['*'], 'page');

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

Однако, наш интерес заключается в третьем аргументе page, где вы можете задать желаемое имя ключа. Мы назовём его orders_page.

Order::paginate(5, ['*'], 'orders_page');

Теперь, если мы обновим страницу, то увидим, что всё работает, мета-данные пагинатора изменились, а ссылка пагинации теперь содержим параметр orders_page.

Screenshot--1-

Способ 2

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

$orders = Order::paginate(5);
$orders->setPageName('custom_page_key');
//...

И результатом будет: custom_page_name

Однако, этот способ работает не так, как многие из вас могли подумать. Передав параметр setPageName вы можете удивиться, почему пагинация не работает. И ответ, на самом деле, прост.

На самом деле, метод setPageName никак не затрагивает запрос к БД. Он лишь изменяет параметр номера страницы в метаданных.

Потому, что, мы сначала получаем результат со стандартными параметрами:

// здесь вызываются стандартные параметры, то есть, ключ номера страницы сейчас `page`
$orders = Order::paginate(5); // коллекция элементов

А после чего, мы вызываем метод setPageName у коллекции результатов, уже полученных из БД. Этим методом, мы просто заменяем параметр в ссылке пагинатора, уже не имея возможности повлиять на формирование запроса, т.к. он уже был выполнен методом paginate.

Как говорится, поздно, мистер, пить боржоми, если запрос к БД уже сделан.

Резюме

В этой статье мы рассмотрели, как работать с пагинатором Laravel, и как передавать кастомные параметры для запроса и метаинформации. Был приведён пример Laravel пагинации с изменением ключа запроса, и передачей номера страницы напрямую.

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

А так же, эта статья является очень полезной для тех, кто не знал, как разместить несколько Laravel пагинаторов на одной странице. Это делается просто, указав уникальный ключ номера страницы для каждого из них.