Skip to content

Фильтры ​

filters() перечисляет фильтры, которые может использовать запрос клиента. У каждого фильтра есть вид, тип значения и набор разрешённых операторов:

php
public function filters(): array
{
    return [
        Filter::partial('name'),
        Filter::exact('status')->defaultOperator(Operator::In),
        Filter::int('views')->operators(),
        Filter::datetime('created_at')->operators(Operator::Gte, Operator::Lte),
        Filter::enum('role', Role::class),
        Filter::scope('popular'),
        Filter::trashed(),
    ];
}

Виды ​

ФабрикаСравнение
Filter::exact('status')= (in для списка)
Filter::partial('name'), beginsWith, endsWithlike
Filter::int, float, bool, date, datetime, enum('status', Status::class)exact с типизированным значением
Filter::scope('popular')скоуп модели, значение — его аргумент (элементы in и границы between — его аргументы)
Filter::callback('search', fn ($query, $value, Operator $operator) => ...)ваше замыкание
Filter::trashed()with, only или без удалённых моделей

Типы значений ​

Тип любого фильтра можно сменить через asInt(), asFloat(), asBool(), asDate(), asDateTime(), asEnum() и asString(). Значение, не подходящее под тип, отклоняется с invalid_value.

  • Фильтр date сравнивает дату без времени.
  • Значение datetime со смещением переводится в часовой пояс приложения.
  • Фильтр datetime принимает и дату без времени и тогда сравнивает по дню в часовом поясе приложения: filter[placed_at]=2026-09-01 совпадает со всем днём, [lt] — до него, [lte] — до его конца, а [between]=2026-09-01,2026-09-30 берёт оба дня целиком. SQL сравнивает колонку с границами дня, поэтому индекс по ней по-прежнему работает.

Операторы ​

Операторы указываются в скобках после имени фильтра:

filter[views]=30                     equality
filter[views][gte]=20&filter[views][lt]=40
filter[views][between]=20,30         inclusive
filter[views][in]=10,30              also filter[views][in][]=10&filter[views][in][]=30
filter[deleted_at][null]=true

Операторы: eq, ne, gt, gte, lt, lte, in, nin, between и null.

По умолчанию фильтр принимает eq, in (точные небулевы фильтры) и null (nullable-фильтры). ->operators(Operator::Gte, Operator::Lte) разрешает перечисленные, а ->operators() без аргументов — все операторы, подходящие под тип. Операторам сравнения нужен упорядочиваемый тип: число или дата.

Модификаторы ​

  • ->defaultOperator(Operator::Between): оператор значения, переданного без оператора, так что filter[created_at]=2026-01-01,2026-01-31 — диапазон; с Operator::Infilter[status]=new,paid — список (скоуп получает элементы как аргументы, как в spatie). Этот оператор разрешается вместе с остальными, и [eq] по-прежнему означает eq.
  • ->nullable(): пустое значение или [null]=true совпадает с NULL, а не игнорируется.
  • ->default('published'): значение, когда запрос клиента не упоминает фильтр.
  • ->column('created_at'): колонка (или скоуп), если она отличается от имени в запросе.
  • ->relation('author.profile'): путь связи, если он отличается от имени.

Фильтрация по связям ​

Точка в имени фильтрует по связи: Filter::int('posts.views') ограничивает пользователей через whereHas('posts'), а если posts подгружена, сужает и загруженные посты. С ->onlyIncluded() фильтр сужает только подгруженные строки и не трогает корень.

Фильтры по одной связи делят один whereHas: при filter[posts.views][gte]=40&filter[posts.title]=Hello пользователю нужен один пост, подходящий под оба условия, и до таких же постов сужаются подгруженные.

Путь через morphTo требует моделей, на которые он может указывать: Filter::exact('commentable.title')->morphTypes(Post::class, Video::class). Если morphTypes() не задан, берутся типы Relationship::morphTo() на том же пути.

Фильтры вложенных определений ​

Relationship::to('posts', PostQuery::class)->withFilters() публикует фильтры PostQuery на корне как filter[posts.<name>] (filter[posts.status]=draft). Они работают как любой фильтр по связи; их значения по умолчанию не применяются.