spatie / laravel-query-builder

Easily build Eloquent queries from API requests
https://spatie.be/docs/laravel-query-builder
MIT License
4k stars 392 forks source link

Multi value delimiter cannot be set individually for single filters #957

Closed cristiancalara closed 1 month ago

cristiancalara commented 1 month ago

Currently, you cannot set a multi-value delimiter individually as:

QueryBuilder::for(Model::class)
    ->allowedFilters([
          AllowedFilter::exact('id', 'ref_id', true, ';'),
          AllowedFilter::exact('voltage', null, true, '|'),
    ])
    ->get();

The second call will overwrite the static value of the delimiter set in the first filter. Added this as a bug as the documentation and the PR feel like suggest you could do that.

I looked a bit at what it will take to actually allow this feature (which is useful, at least for filters). If we consider that the class QueryBuilderRequest was "internal", we could update and: -> have the Filter class hold a new attribute called filterDelimiter that would default to the current static value; -> send the allowedFilters list to $this->request->filters() call https://github.com/spatie/laravel-query-builder/blob/ed71451f15d74df8fcf38d905d1afe7549ee7fd8/src/Concerns/FiltersQuery.php#L36 -> update the https://github.com/spatie/laravel-query-builder/blob/ed71451f15d74df8fcf38d905d1afe7549ee7fd8/src/QueryBuilderRequest.php#L109 and use the allowedFilters and filterDelimiter in getFilterValue

Obviously the above is quite hacky and not that elegant. Another option might be to transform $filterArrayValueDelimiter into an dictionary and then we'd have unique keys (maybe request from user or somehow automatically create one) across the app and do something like:

QueryBuilder::for(Model::class)
    ->allowedFilters([
          AllowedFilter::exact('id', 'ref_id', true, ['key' => 'model_name_or_class_id', 'value' => ';']),
          AllowedFilter::exact('voltage', null, true, ['key' => 'model_name_or_class_voltage', 'value' => '|']),
    ])
    ->get();

Let me know any thoughts on the above and if you think any of the suggested implementations are worth a PR.

Thanks for a great package!