### Install Laravel Query Builder Source: https://spatie.be/docs/laravel-query-builder/v6/installation-setup Install the package using Composer. This command adds the package to your project's dependencies. ```bash composer require spatie/laravel-query-builder ``` -------------------------------- ### Check Laravel Query Builder Version Source: https://spatie.be/docs/laravel-query-builder/v6/advanced-usage/front-end-implementation Use this command to determine the installed version of the spatie/laravel-query-builder package. ```bash composer show spatie/laravel-query-builder ``` -------------------------------- ### Combine Query Builder with Existing Queries Source: https://spatie.be/docs/laravel-query-builder/v6 Start a QueryBuilder instance from an existing Eloquent query builder. This allows chaining custom scopes and QueryBuilder methods. ```php $query = User::where('active', true); $userQuery = QueryBuilder::for($query) // start from an existing Builder instance ->withTrashed() // use your existing scopes ->allowedIncludes('posts', 'permissions') ->where('score', '>', 42); // chain on any of Laravel's query builder methods ``` -------------------------------- ### Filter Users by Name Source: https://spatie.be/docs/laravel-query-builder/v6 Filter a User query based on a 'name' parameter from the request. This example demonstrates basic filtering functionality. ```php use Spatie\QueryBuilder\QueryBuilder; $users = QueryBuilder::for(User::class) ->allowedFilters('name') ->get(); // all `User`s that contain the string "John" in their name ``` -------------------------------- ### Using a Base Query with Query Builder Source: https://spatie.be/docs/laravel-query-builder/v6/advanced-usage/extending-query-builder Specify a base query instead of a model FQCN to start building your query. You can chain any of Laravel's query methods and Query Builder specific methods. ```php QueryBuilder::for(User::where('id', 42)) // base query instead of model ->allowedIncludes(['posts']) ->where('activated', true) // chain on any of Laravel's query methods ->first(); // we only need one specific user ``` -------------------------------- ### Publish Configuration File Source: https://spatie.be/docs/laravel-query-builder/v6/installation-setup Optionally publish the configuration file to customize package settings. This command uses Artisan to publish the vendor assets. ```bash php artisan vendor:publish --provider="Spatie\QueryBuilder\QueryBuilderServiceProvider" --tag="query-builder-config" ``` -------------------------------- ### Select Fields with Query Builder Instance Source: https://spatie.be/docs/laravel-query-builder/v6/features/selecting-fields You can also use the `select` method on an existing query builder instance to refine the selected fields. ```php use App\Models\User; $query = User::query(); $users = $query->select('name', 'email')->get(); ``` -------------------------------- ### Default Configuration Parameters Source: https://spatie.be/docs/laravel-query-builder/v6/installation-setup These are the default query string parameters used by the package for include, filter, sort, fields, and append. You can customize these in the published config file. ```php return [ /* * By default the package will use the `include`, `filter` * and `sort` query parameters as described in the readme. * * You can customize these query string parameters here. */ 'parameters' => [ 'include' => 'include', 'filter' => 'filter', 'sort' => 'sort', 'fields' => 'fields', 'append' => 'append', ], /* * Related model counts are included using the relationship name suffixed with this string. * For example: GET /users?include=postsCount */ 'count_suffix' => 'Count', /* * Related model exists are included using the relationship name suffixed with this string. * For example: GET /users?include=postsExists */ 'exists_suffix' => 'Exists', /* * By default the package will throw an `InvalidFilterQuery` exception when a filter in the * URL is not allowed in the `allowedFilters()` method. */ 'disable_invalid_filter_query_exception' => false, /* * By default the package will throw an `InvalidSortQuery` exception when a sort in the * URL is not allowed in the `allowedSorts()` method. */ 'disable_invalid_sort_query_exception' => false, /* * By default the package will throw an `InvalidIncludeQuery` exception when an include in the * URL is not allowed in the `allowedIncludes()` method. */ 'disable_invalid_includes_query_exception' => false, /* * By default, the package expects relationship names to be snake case plural when using fields[relationship]. * For example, fetching the id and name for a userOwner relation would look like this: * GET /users?include=userOwner&fields[user_owners]=id,name * * Set this to `false` if you don't want that and keep the requested relationship names as-is and allows you to ]; ``` -------------------------------- ### Define a Custom Include Class Source: https://spatie.be/docs/laravel-query-builder/v6/features/including-relationships Implement `IncludeInterface` to create reusable custom include logic. The `__invoke` method receives the query builder and include name, allowing complex query modifications. ```php use Spatie\QueryBuilder\Includes\IncludeInterface; use Illuminate\Database\Eloquent\Builder; use App\Models\Post; class AggregateInclude implements IncludeInterface { protected string $column; protected string $function; public function __construct(string $column, string $function) { $this->column = $column; $this->function = $function; } public function __invoke(Builder $query, string $relations) { $query->withAggregate($relations, $this->column, $this->function); } } // In your controller for the following request: // GET /posts?include=comments_sum_votes $posts = QueryBuilder::for(Post::class) ->allowedIncludes([ AllowedInclude::custom('comments_sum_votes', new AggregateInclude('votes', 'sum'), 'comments'), ]) ->get(); // every post in $posts will contain a `comments_sum_votes` property ``` -------------------------------- ### Implementing Custom Filters Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Create reusable custom filters by implementing the `Spatie\QueryBuilder\Filters\Filter` interface and using `AllowedFilter::custom()`. The `__invoke` method handles the query modification based on the provided value and property name. ```php use Spatie\QueryBuilder\Filters\Filter; use Illuminate\Database\Eloquent\Builder; class FiltersUserPermission implements Filter { public function __invoke(Builder $query, $value, string $property) { $query->whereHas('permissions', function (Builder $query) use ($value) { $query->where('name', $value); }); } } // In your controller for the following request: // GET /users?filter[permission]=createPosts $users = QueryBuilder::for(User::class) ->allowedFilters([ AllowedFilter::custom('permission', new FiltersUserPermission), ]) ->get(); // $users will contain all users that have the `createPosts` permission ``` -------------------------------- ### Select Specific Fields Source: https://spatie.be/docs/laravel-query-builder/v6/features/selecting-fields Use the `select` method to specify which columns to retrieve from the database. This is useful for performance optimization and security. ```php use App\Models\User; $users = User::select('name', 'email')->get(); ``` -------------------------------- ### Include relationships with nested constraints Source: https://spatie.be/docs/laravel-query-builder/v6/features/including-relationships You can include nested relationships with constraints by chaining the `with` method and using closures for each level of nesting. ```php use App\Models\User; $users = User::with(['posts' => function ($query) { $query->where('is_published', true); $query->with(['comments' => function ($query) { $query->where('is_approved', true); }]); }])->get(); ``` -------------------------------- ### Configuration Options Source: https://spatie.be/docs/laravel-query-builder/v6/installation-setup Configuration settings for managing relation and field name conversions in the Laravel Query Builder. ```php return [ /* * request the fields using a camelCase relationship name: * GET /users?include=userOwner&fields[userOwner]=id,name */ 'convert_relation_names_to_snake_case_plural' => true, /* * This is an alternative to the previous option if you don't want to use default snake case plural for fields[relationship]. * It resolves the table name for the related model using the Laravel model class and, based on your chosen strategy, * matches it with the fields[relationship] provided in the request. * * Set this to one of `snake_case`, `camelCase` or `none` if you want to enable table name resolution in addition to the relation name resolution. * `snake_case` => Matches table names like 'topOrders' to `fields[top_orders]` * `camelCase` => Matches table names like 'top_orders' to 'fields[topOrders]' * `none` => Uses the exact table name */ 'convert_relation_table_name_strategy' => false, /* * By default, the package expects the field names to match the database names * For example, fetching the field named firstName would look like this: * GET /users?fields=firstName * * Set this to `true` if you want to convert the firstName into first_name for the underlying query */ 'convert_field_names_to_snake_case' => false, ]; ``` -------------------------------- ### Basic Relationship Inclusion Source: https://spatie.be/docs/laravel-query-builder/v6/features/including-relationships Load a single relationship for all retrieved models. Ensure the relationship is allowed using `allowedIncludes()`. ```php // GET /users?include=posts $users = QueryBuilder::for(User::class) ->allowedIncludes(['posts']) ->get(); // $users will have all their `posts()` related models loaded ``` -------------------------------- ### Basic Field Selection Source: https://spatie.be/docs/laravel-query-builder/v6/features/selecting-fields Fetch only specified fields for a model. Use `allowedFields` to define the selectable columns and the `fields` query parameter to specify which ones to retrieve. ```php QueryBuilder::for(User::class) ->allowedFields(['id', 'name']) ->toSql(); ``` ```http GET /users?fields[users]=id,name ``` ```sql SELECT "id", "name" FROM "users" ``` -------------------------------- ### Set Global Delimiter in Service Provider Source: https://spatie.be/docs/laravel-query-builder/v6/advanced-usage/multi-value-delimiter Apply a custom delimiter globally by defining it within your application's Service Provider's boot method. ```php // YourServiceProvider.php public function boot() { QueryBuilderRequest::setArrayValueDelimiter(';'); } ``` -------------------------------- ### Multiple Relationship Inclusion Source: https://spatie.be/docs/laravel-query-builder/v6/features/including-relationships Load multiple relationships by separating them with a comma in the 'include' parameter. All specified relationships must be allowed. ```php // GET /users?include=posts,permissions $users = QueryBuilder::for(User::class) ->allowedIncludes(['posts', 'permissions']) ->get(); // $users will contain all users with their posts and permissions loaded ``` -------------------------------- ### Sort Users by ID Source: https://spatie.be/docs/laravel-query-builder/v6 Sort User models by their 'id' in ascending order based on a 'sort' parameter in the request. This demonstrates basic sorting. ```php $users = QueryBuilder::for(User::class) ->allowedSorts('id') ->get(); // all `User`s sorted by ascending id ``` -------------------------------- ### Include multiple relationships Source: https://spatie.be/docs/laravel-query-builder/v6/features/including-relationships You can include multiple relationships by passing an array of relationship names to the `with` method. This allows for efficient loading of several related models in one query. ```php use App\Models\User; $users = User::with(['posts', 'comments'])->get(); ``` -------------------------------- ### Include a single relationship Source: https://spatie.be/docs/laravel-query-builder/v6/features/including-relationships Use the `with` method to eager load a single relationship. This is useful for reducing the number of database queries when accessing related data. ```php use App\Models\User; $users = User::with('posts')->get(); ``` -------------------------------- ### Include relationships with multiple constraints Source: https://spatie.be/docs/laravel-query-builder/v6/features/including-relationships Multiple constraints can be applied to a relationship using a closure. This provides fine-grained control over which related models are loaded. ```php use App\Models\User; $users = User::with(['posts' => function ($query) { $query->where('is_published', true)->orderBy('created_at', 'desc'); }])->get(); ``` -------------------------------- ### Basic Sorting by Column Source: https://spatie.be/docs/laravel-query-builder/v6/features/sorting Sorts the results by a specified column in ascending order. Use this for simple, direct sorting needs. ```php use App\Models\YourModel; YourModel::query()->allowedSorts('name')->get(); ``` -------------------------------- ### Filtering with Wildcards Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Perform partial string matching using SQL LIKE operators. This is useful for searching text fields. ```php use App\Models\User; $users = User::where("name", "like", "%John%") ->get(); $users = User::where("name", "like", "John%") ->get(); $users = User::where("name", "like", "%John") ->get(); ``` -------------------------------- ### Sorting by Multiple Columns Source: https://spatie.be/docs/laravel-query-builder/v6/features/sorting Allows sorting by multiple columns, specifying the order for each. Useful for hierarchical sorting. ```php use App\Models\YourModel; YourModel::query()->allowedSorts('name', 'created_at')->get(); ``` -------------------------------- ### Set Delimiter via Middleware Source: https://spatie.be/docs/laravel-query-builder/v6/advanced-usage/multi-value-delimiter Use middleware to apply a specific delimiter for a subset of controllers or routes, providing granular control over query parameter parsing. ```php // ApplySemicolonDelimiterMiddleware.php public function handle($request, $next) { QueryBuilderRequest::setArrayValueDelimiter(';'); return $next($request); } ``` -------------------------------- ### Handling Disallowed Sorts Source: https://spatie.be/docs/laravel-query-builder/v6/features/sorting Demonstrates that attempting to sort by a property not listed in `allowedSorts` (e.g., 'password') will throw an `InvalidSortQuery` exception. ```php // GET /users?sort=password $users = QueryBuilder::for(User::class) ->allowedSorts(['name']) ->get(); // Will throw an `InvalidSortQuery` exception as `password` is not an allowed sorting property ``` -------------------------------- ### Select User Fields Source: https://spatie.be/docs/laravel-query-builder/v6 Select specific fields ('id', 'email') for User models from the request. This limits the returned attributes to only those specified. ```php $users = QueryBuilder::for(User::class) ->allowedFields(['id', 'email']) ->get(); // the fetched `User`s will only have their id & email set ``` -------------------------------- ### Define a Callback Include Source: https://spatie.be/docs/laravel-query-builder/v6/features/including-relationships Use `AllowedInclude::callback` to define simple, inline custom includes with a Closure. The Closure receives the query builder and can be used to add specific query constraints. ```php QueryBuilder::for(User::class) ->allowedIncludes([ AllowedInclude::callback('latest_post', function (Builder $query) { $query->latestOfMany(); }), ]); ``` -------------------------------- ### Nested Relationship Inclusion Source: https://spatie.be/docs/laravel-query-builder/v6/features/including-relationships Load nested relationships using dot notation in the 'include' parameter. Ensure all levels of the nested relationship are allowed. ```php // GET /users?include=posts.comments,permissions $users = QueryBuilder::for(User::class) ->allowedIncludes(['posts.comments', 'permissions']) ->get(); // $users will contain all users with their posts, comments on their posts and permissions loaded ``` -------------------------------- ### Select Fields from Relationships Source: https://spatie.be/docs/laravel-query-builder/v6/features/selecting-fields When including relationships, you can select specific fields from both the main model and its related models using dot notation. ```php use App\Models\User; $users = User::with(['posts' => function ($query) { $query->select('id', 'user_id', 'title'); }])->select('id', 'name')->get(); ``` -------------------------------- ### Setting Default Filter Values Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Specify default values for filters when no value is provided in the request. Useful for boolean filters. ```php QueryBuilder::for(User::class) ->allowedFilters([ AllowedFilter::exact('name')->default('Joe'), AllowedFilter::scope('deleted')->default(false), AllowedFilter::scope('permission')->default(null), ]) ->get(); ``` -------------------------------- ### Include User Posts Source: https://spatie.be/docs/laravel-query-builder/v6 Include the 'posts' relationship for User models based on an 'include' parameter in the request. This allows eager loading of related data. ```php $users = QueryBuilder::for(User::class) ->allowedIncludes('posts') ->get(); // all `User`s with their `posts` loaded ``` -------------------------------- ### Include relationships with constraints Source: https://spatie.be/docs/laravel-query-builder/v6/features/including-relationships You can apply constraints to included relationships using a closure. This allows you to filter or select specific related models during the eager loading process. ```php use App\Models\User; $users = User::with(['posts' => function ($query) { $query->where('is_published', true); }])->get(); ``` -------------------------------- ### Exact Filters for Specific Fields Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Use exact filters to match specific values for fields like 'id' or 'admin'. This is useful for precise data retrieval. ```php use Spatie\QueryBuilder\QueryBuilder; use Spatie\QueryBuilder\AllowedFilter; $users = QueryBuilder::for(User::class) ->allowedFilters([ AllowedFilter::exact('id'), AllowedFilter::exact('admin'), ]) ->get(); // $users will contain all admin users with id 1, 2, 3, 4 or 5 ``` -------------------------------- ### Scope Filters for Local Scopes Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Apply local scopes defined on your models as filters. This allows leveraging existing scope logic for filtering via URL parameters. Use filter aliases for more appropriate filter names. ```php QueryBuilder::for(User::class) ->allowedFilters([ AllowedFilter::scope('unconfirmed', 'whereHasUnconfirmedEmail'), // `?filter[unconfirmed]=1` will now add the `scopeWhereHasUnconfirmedEmail` to your query ]); ``` -------------------------------- ### Sorting with Default Order Source: https://spatie.be/docs/laravel-query-builder/v6/features/sorting Specifies a default sorting column and direction when no sorting parameter is provided. Ensures consistent results. ```php use App\Models\YourModel; YourModel::query()->defaultSort('-created_at')->get(); ``` -------------------------------- ### Default Sort by Name (Ascending) Source: https://spatie.be/docs/laravel-query-builder/v6/features/sorting Applies a default sort order by 'name' if no `sort` parameter is provided in the request. Both 'name' and 'street' are allowed sorts. ```php // GET /users $users = QueryBuilder::for(User::class) ->defaultSort('name') ->allowedSorts('name', 'street') ->get(); // Will retrieve the users sorted by name ``` -------------------------------- ### Default Includes with Laravel's `with()` Source: https://spatie.be/docs/laravel-query-builder/v6/features/including-relationships Use Laravel's built-in `with()` method to always include relationships by default, alongside query builder allowed includes. ```php $users = QueryBuilder::for(User::class) ->allowedIncludes(['friends']) ->with('posts') // posts will always by included, friends can be requested ->withCount('posts') ->withExists('posts') ->get(); ``` -------------------------------- ### Exact Filtering with Boolean and Array Values Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering The query builder automatically maps 'true'/'false' to booleans and comma-separated lists to arrays for exact filtering. ```php use Spatie\QueryBuilder\AllowedFilter; use Spatie\QueryBuilder\QueryBuilder; use App\Models\User; // GET /users?filter[id]=1,2,3,4,5&filter[admin]=true $users = QueryBuilder::for(User::class) ->allowedFilters([ AllowedFilter::exact('id'), AllowedFilter::exact('admin'), ]) ->get(); // $users will contain users with IDs 1 through 5 AND where admin is true. ``` -------------------------------- ### Sorting by Multiple Properties Source: https://spatie.be/docs/laravel-query-builder/v6/features/sorting Sorts results by 'name' in ascending order, with a secondary sort by 'street' in descending order. Both properties are explicitly allowed. ```php // GET /users?sort=name,-street $users = QueryBuilder::for(User::class) ->allowedSorts(['name', 'street']) ->get(); // $users will be sorted by name in ascending order with a secondary sort on street in descending order. ``` -------------------------------- ### Using Filter Aliases Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Specify aliases for filters using `AllowedFilter::exact()` to map user-friendly names to potentially complex or sensitive database column names. This improves API clarity and security. ```php use Spatie\QueryBuilder\AllowedFilter; // GET /users?filter[name]=John $users = QueryBuilder::for(User::class) ->allowedFilters(AllowedFilter::exact('name', 'user_passport_full_name')) // will filter by the `user_passport_full_name` column ->get(); ``` -------------------------------- ### Custom Sorting Logic Source: https://spatie.be/docs/laravel-query-builder/v6/features/sorting Defines custom sorting logic using a closure for complex sorting requirements. This allows for dynamic sorting based on specific conditions. ```php use App\Models\YourModel; use Illuminate\Database\Eloquent\Builder; YourModel::query()->allowedSorts( AllowedSort::custom('name', function (Builder $query, string $direction) { $query->orderBy('last_name', $direction); }) )->get(); ``` -------------------------------- ### Handling Disallowed Fields Source: https://spatie.be/docs/laravel-query-builder/v6/features/selecting-fields Attempting to select a field not listed in `allowedFields` will result in an `InvalidFieldQuery` exception. Ensure all requested fields are explicitly allowed. ```php $users = QueryBuilder::for(User::class) ->allowedFields('name') ->get(); // GET /users?fields[users]=email will throw an `InvalidFieldQuery` exception as `email` is not an allowed field. ``` -------------------------------- ### Sorting with Allowed Includes Source: https://spatie.be/docs/laravel-query-builder/v6/features/sorting Sorts results based on a relationship's column, provided the relationship is also allowed to be included. Ensures data integrity and security. ```php use App\Models\YourModel; YourModel::query()->allowedIncludes(['user'])->allowedSorts('user.name')->get(); ``` -------------------------------- ### Basic Partial Filtering Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Allows filtering by partial attribute values. By default, string values passed to allowedFilters are converted to partial filters, using LIKE LOWER(%value%). ```php use Spatie\QueryBuilder\QueryBuilder; use App\Models\User; // GET /users?filter[name]=john&filter[email]=gmail $users = QueryBuilder::for(User::class) ->allowedFilters(['name', 'email']) ->get(); // $users will contain all users with "john" in their name AND "gmail" in their email address ``` -------------------------------- ### Include nested relationships Source: https://spatie.be/docs/laravel-query-builder/v6/features/including-relationships Nested relationships can be included using dot notation. This allows you to eager load relationships of relationships, further optimizing data retrieval. ```php use App\Models\User; $users = User::with('posts.comments')->get(); ``` -------------------------------- ### Custom Sort with Multiple Columns Source: https://spatie.be/docs/laravel-query-builder/v6/features/sorting Combines custom sorting logic with the ability to sort by multiple columns. This provides granular control over complex sorting scenarios. ```php use App\Models\YourModel; use Illuminate\Database\Eloquent\Builder; YourModel::query()->allowedSorts( AllowedSort::custom('name', function (Builder $query, string $direction) { $query->orderBy('last_name', $direction); }), 'created_at' )->get(); ``` -------------------------------- ### Custom Sort Implementation (String Length) Source: https://spatie.be/docs/laravel-query-builder/v6/features/sorting Defines a custom sort logic using an invokable class `StringLengthSort` to sort by the length of a string column. The sort is aliased as 'name-length'. ```php class StringLengthSort implements Spatie QueryBuilder Sorts Sort { public function __invoke(Builder $query, bool $descending, string $property) { $direction = $descending ? 'DESC' : 'ASC'; $query->orderByRaw("LENGTH(`{$property}`) {$direction}"); } } ``` ```php // GET /users?sort=name-length $users = QueryBuilder::for(User::class) ->allowedSorts([ AllowedSort::custom('name-length', new StringLengthSort(), 'name'), ]) ->get(); // The requested `name-length` sort alias will invoke `StringLengthSort` with the `name` column name. ``` -------------------------------- ### Operator Filters for Comparisons Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Employ operator filters to query data based on comparison operators like GREATER_THAN, LESS_THAN, etc. Ensure the FilterOperator enum is imported. ```php use Spatie\QueryBuilder\AllowedFilter; use Spatie\QueryBuilder\Enums\FilterOperator; // GET /users?filter[salary]=3000 $users = QueryBuilder::for(User::class) ->allowedFilters([ AllowedFilter::operator('salary', FilterOperator::GREATER_THAN), ]) ->get(); // $users will contain all users with a salary greater than 3000 ``` -------------------------------- ### Filtering with Scopes Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Utilize local scopes defined on your Eloquent models for reusable filtering logic. This promotes cleaner and more maintainable code. ```php use App\Models\User; $users = User::withScope("active", true)->get(); $users = User::withScope("hasRole", "admin") ->get(); ``` -------------------------------- ### Basic Sorting by Name (Descending) Source: https://spatie.be/docs/laravel-query-builder/v6/features/sorting Sorts results by the 'name' property in descending order. The `allowedSorts` method explicitly permits sorting by 'name'. ```php // GET /users?sort=-name $users = QueryBuilder::for(User::class) ->allowedSorts('name') ->get(); // $users will be sorted by name and descending (Z -> A) ``` -------------------------------- ### Selecting Fields for Included Relations Source: https://spatie.be/docs/laravel-query-builder/v6/features/selecting-fields Control which fields are fetched for included relationships. Use dot notation in `allowedFields` and ensure relation fields required by Eloquent are included. ```php QueryBuilder::for(Post::class) ->allowedFields('authors.id', 'authors.name') ->allowedIncludes('author'); // All posts will be fetched including _only_ the name of the author. ``` ```http GET /posts?include=author&fields[authors]=id,name ``` -------------------------------- ### Filtering with Date Ranges Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Filter records based on date ranges using operators like 'before' and 'after'. This is crucial for time-series data analysis. ```php use App\Models\User; use Carbon\Carbon; $users = User::where("created_at", "<", Carbon::now()->subDay()) ->get(); $users = User::where("created_at", ">", Carbon::now()->subDays(5)) ->get(); ``` -------------------------------- ### Including Related Model Existence Source: https://spatie.be/docs/laravel-query-builder/v6/features/including-relationships Allow requesting the existence of related models using an 'Exists' suffix. This uses Laravel's `withExists` method. ```php // GET /users?include=postsExists,friendsExists $users = QueryBuilder::for(User::class) ->allowedIncludes([ 'posts', // allows including `posts` or `postsCount` or `postsExists` AllowedInclude::exists('friendsExists'), // only allows include the existence of `friends()` related models ]); // every user in $users will contain a `posts_exists` and `friends_exists` property ``` -------------------------------- ### Filtering with Multiple Values (OR) Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Specify multiple matching filter values by passing a comma-separated list. This applies an OR condition for the specified filter. ```php use Spatie\QueryBuilder\QueryBuilder; use App\Models\User; // GET /users?filter[name]=seb,freek $users = QueryBuilder::for(User::class) ->allowedFilters(['name']) ->get(); // $users will contain all users that contain "seb" OR "freek" in their name ``` -------------------------------- ### Making Filters Nullable Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Mark filters as nullable to retrieve entries where the filtered value is null. This allows applying the filter with an empty value. ```php // GET /user?filter[name]=&filter[permission]= QueryBuilder::for(User::class) ->allowedFilters([ AllowedFilter::exact('name')->nullable(), AllowedFilter::scope('permission')->nullable(), ]) ->get(); ``` -------------------------------- ### Multiple Default Sorts Source: https://spatie.be/docs/laravel-query-builder/v6/features/sorting Defines multiple default sort criteria: descending by 'street' and then ascending by 'name'. Both are allowed. ```php // GET /users $users = QueryBuilder::for(User::class) ->defaultSort('-street', 'name') ->allowedSorts('name', 'street') ->get(); // Will retrieve the users sorted descendingly by street than in ascending order by name ``` -------------------------------- ### Append Request Query Parameters to Pagination Source: https://spatie.be/docs/laravel-query-builder/v6/advanced-usage/pagination Use the `appends` method on the `LengthAwarePaginator` to include request query parameters in the pagination JSON. This is useful for maintaining filters and other query parameters across paginated views. ```php $users = QueryBuilder::for(User::class) ->allowedFilters(['name', 'email']) ->paginate() ->appends(request()->query()); ``` -------------------------------- ### Exact Filtering Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Use exact filters for IDs, boolean values, or literal strings to avoid partial matches. This ensures that only values matching exactly are returned. ```php use Spatie\QueryBuilder\AllowedFilter; use Spatie\QueryBuilder\QueryBuilder; use App\Models\User; // GET /users?filter[name]=John%20Doe $users = QueryBuilder::for(User::class) ->allowedFilters([AllowedFilter::exact('name')]) ->get(); // only users with the exact name "John Doe" ``` -------------------------------- ### Default Sort by Name (Descending) Source: https://spatie.be/docs/laravel-query-builder/v6/features/sorting Sets 'name' as the default sort property in descending order. 'name' and 'street' are permitted sorting properties. ```php // GET /users $users = QueryBuilder::for(User::class) ->defaultSort('-name') ->allowedSorts('name', 'street') ->get(); // Will retrieve the users sorted descendingly by name ``` -------------------------------- ### Defining Callback Filters Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Callback filters allow for small, custom filter logic using `AllowedFilter::callback()`. The provided callable receives the query builder, the filter value, and the filter name, enabling direct modification of query constraints. ```php QueryBuilder::for(User::class) ->allowedFilters([ AllowedFilter::callback('has_posts', function (Builder $query, $value) { $query->whereHas('posts'); }), ]); ``` ```php QueryBuilder::for(User::class) ->allowedFilters([ AllowedFilter::callback('has_posts', fn (Builder $query) => $query->whereHas('posts')), ]); ``` -------------------------------- ### Disable InvalidFilterQuery Exception Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Configure the package to not throw an InvalidFilterQuery exception when a filter is not explicitly allowed. This does not enable the filter, only disables the exception. ```php 'disable_invalid_filter_query_exception' => true ``` -------------------------------- ### Including Related Model Count Source: https://spatie.be/docs/laravel-query-builder/v6/features/including-relationships Allow requesting the count of related models using a 'Count' suffix. This uses Laravel's `withCount` method. ```php // GET /users?include=postsCount,friendsCount $users = QueryBuilder::for(User::class) ->allowedIncludes([ 'posts', // allows including `posts` or `postsCount` or `postsExists` AllowedInclude::count('friendsCount'), // only allows include the number of `friends()` related models ]); // every user in $users will contain a `posts_count` and `friends_count` property ``` -------------------------------- ### Dynamic Operator Filters Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Utilize dynamic operator filters to allow the operator to be specified within the filter value in the URL. This provides flexibility in query conditions. ```php use Spatie\QueryBuilder\AllowedFilter; use Spatie\QueryBuilder\Enums\FilterOperator; // GET /users?filter[salary]=>3000 $users = QueryBuilder::for(User::class) ->allowedFilters([ AllowedFilter::operator('salary', FilterOperator::DYNAMIC), ]) ->get(); // $users will contain all users with a salary greater than 3000 ``` -------------------------------- ### Basic Filtering Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Filter query results based on a given field and value. This is a common way to narrow down results. ```php use App\Models\User; $users = User::where("active", true)->get(); $users = User::where("name", "John") ->where("age", "<", 30) ->get(); $users = User::where("active", true) ->where("name", "John") ->get(); ``` -------------------------------- ### Alias a Relationship for Inclusion Source: https://spatie.be/docs/laravel-query-builder/v6/features/including-relationships Use `AllowedInclude::relationship` to specify a shorter, friendlier name for an included relationship. This is useful for cleaner API endpoints. ```php use Spatie\QueryBuilder\AllowedInclude; // GET /users?include=profile $users = QueryBuilder::for(User::class) ->allowedIncludes(AllowedInclude::relationship('profile', 'userProfile')) // will include the `userProfile` relationship ->get(); ``` -------------------------------- ### Set Per-Feature Array Value Delimiters Source: https://spatie.be/docs/laravel-query-builder/v6/advanced-usage/multi-value-delimiter Customize the delimiter for specific query builder features like includes, appends, fields, sorts, or filters individually. ```php QueryBuilderRequest::setIncludesArrayValueDelimiter(';'); // Includes QueryBuilderRequest::setAppendsArrayValueDelimiter(';'); // Appends QueryBuilderRequest::setFieldsArrayValueDelimiter(';'); // Fields QueryBuilderRequest::setSortsArrayValueDelimiter(';'); // Sorts QueryBuilderRequest::setFilterArrayValueDelimiter(';'); // Filter ``` -------------------------------- ### Exact Value Filtering Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Perform an exact match filter on a specific field. Useful when you need to ensure the value is precisely what you're looking for. ```php use App\Models\User; $users = User::where("name", "John") ->get(); ``` -------------------------------- ### Filtering with Not Like Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Exclude records where a specific field matches a pattern using SQL NOT LIKE operators. ```php use App\Models\User; $users = User::where("name", "not like", "%John%") ->get(); ``` -------------------------------- ### Aliasing Sort Field Source: https://spatie.be/docs/laravel-query-builder/v6/features/sorting Allows sorting by a user-facing alias ('street') that maps to a different actual column name ('actual_column_street') in the database. Supports descending order via '-street'. ```php // GET /users?sort=-street $users = QueryBuilder::for(User::class) ->allowedSorts([ AllowedSort::field('street', 'actual_column_street'), ]) ->get(); ``` -------------------------------- ### Filtering with Null Values Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Filter records where a specific field is either null or not null. This is essential for handling missing data. ```php use App\Models\User; $users = User::whereNull("email") ->get(); $users = User::whereNotNull("email") ->get(); ``` -------------------------------- ### Custom Sort with Default Descending Direction Source: https://spatie.be/docs/laravel-query-builder/v6/features/sorting Configures a custom sort to default to descending order using `defaultDirection(SortDirection::DESCENDING)`. This custom sort is then applied as both an allowed and default sort. ```php $customSort = AllowedSort::custom('custom-sort', new SentSort())->defaultDirection(SortDirection::DESCENDING); $users = QueryBuilder::for(User::class) ->allowedSorts($customSort) ->defaultSort($customSort) ->get(); ``` -------------------------------- ### Ignoring Specific Filter Values Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Prevent filters from being applied when certain values are submitted using the `ignore()` method. This is useful for handling default or unwanted input values gracefully. ```php QueryBuilder::for(User::class) ->allowedFilters([ AllowedFilter::exact('name')->ignore(null), ]) ->get(); ``` ```php // GET /user?filter[name]=forbidden,John%20Doe QueryBuilder::for(User::class) ->allowedFilters([ AllowedFilter::exact('name')->ignore('forbidden'), ]) ->get(); // Returns only users where name matches 'John Doe' // GET /user?filter[name]=ignored,ignored_too QueryBuilder::for(User::class) ->allowedFilters([ AllowedFilter::exact('name')->ignore(['ignored', 'ignored_too']), ]) ->get(); // Filter does not get applied because all requested values are ignored. ``` -------------------------------- ### Disabling Sorting Source: https://spatie.be/docs/laravel-query-builder/v6/features/sorting Explicitly disables sorting for a query. Use this when sorting is not desired or needs to be controlled elsewhere. ```php use App\Models\YourModel; YourModel::query()->disableSorts()->get(); ``` -------------------------------- ### Nested BelongsTo Relationship Filters Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Filter through nested BelongsTo relationships using dot notation, like 'post.author'. This allows filtering based on properties of deeply nested related models. ```php QueryBuilder::for(Comment::class) ->allowedFilters([ AllowedFilter::belongsTo('author_post_id', 'post.author'), ]) ->get(); ``` -------------------------------- ### Filtering with Not In Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Exclude records where a specific field matches any value within a given array. This is useful for 'NOT IN' conditions. ```php use App\Models\User; $users = User::whereNotIn("name", ["John", "Jane"]) ->get(); ``` -------------------------------- ### Filtering Related Properties with Dot Notation Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Filter properties of related models using dot notation, such as 'posts.title'. By default, this adds a `whereHas` clause. Set the third parameter to `false` to disable this behavior and pass the raw value. ```php $addRelationConstraint = false; QueryBuilder::for(User::class) ->join('posts', 'posts.user_id', 'users.id') ->allowedFilters(AllowedFilter::exact('posts.title', null, $addRelationConstraint)); ``` -------------------------------- ### Querying Soft Deleted Models Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Use `AllowedFilter::trashed()` to query models that support Laravel's soft delete feature. The filter responds to values like 'with', 'only', or any other value to include, only show, or exclude soft-deleted records, respectively. ```php QueryBuilder::for(Booking::class) ->allowedFilters([ AllowedFilter::trashed(), ]); // GET /bookings?filter[trashed]=only will only return soft deleted models ``` -------------------------------- ### Override Delimiter for a Single Filter Source: https://spatie.be/docs/laravel-query-builder/v6/advanced-usage/multi-value-delimiter Specify a custom delimiter directly when defining an allowed filter, allowing unique parsing rules for specific filter parameters. ```php AllowedFilter::exact('id', 'ref_id', true, ';'); ``` -------------------------------- ### BelongsTo Relationship Filters Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Filter based on a BelongsTo relationship. You can specify the relationship name directly or use an alias for the foreign key. ```php QueryBuilder::for(Comment::class) ->allowedFilters([ AllowedFilter::belongsTo('post'), ]) ->get(); ``` ```php QueryBuilder::for(Comment::class) ->allowedFilters([ AllowedFilter::belongsTo('post_id', 'post'), ]) ->get(); ``` -------------------------------- ### Filtering with Multiple Values Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Filter records where a specific field matches any value within a given array. This is useful for 'OR' conditions on a single field. ```php use App\Models\User; $users = User::whereIn("name", ["John", "Jane"]) ->get(); ``` -------------------------------- ### Filtering with JSON Values Source: https://spatie.be/docs/laravel-query-builder/v6/features/filtering Filter records based on values within JSON columns. This requires the database to support JSON types. ```php use App\Models\User; $users = User::whereJsonContains("options", ["feature_x" => true]) ->get(); $users = User::where("options->language", "en") ->get(); ``` -------------------------------- ### Set Global Array Value Delimiter Source: https://spatie.be/docs/laravel-query-builder/v6/advanced-usage/multi-value-delimiter Overwrite the default delimiter for all array values in query builder requests. This is useful when filter values themselves contain commas. ```php QueryBuilderRequest::setArrayValueDelimiter('|'); QueryBuilder::for(Model::class) ->allowedFilters(AllowedFilter::exact('voltage')) ->get(); // filters: [ 'voltage' => [ '12,4V', '4,7V', '2,1V' ]] ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.