Now it's time to take care of the second part of the client's description of the Tours List: filtering and ordering.
Task Description From Client
- Users can filter (search) the results by
priceFrom
,priceTo
,dateFrom
(from thatstartingDate
) anddateTo
(until thatstartingDate
). - User can sort the list by
price
asc and desc. They will always be sorted, after every additional user-provided filter, bystartingDate
asc.
Filtering Tours: Eloquent when()
First, let's take care of the filter.
Here's our Controller at the moment:
app/Http/Controllers/Api/V1/TourController.php:
public function index(Travel $travel){ $tours = $travel->tours() ->orderBy('starting_date') ->paginate(); return TourResource::collection($tours);}
And our goal is to process the endpoint like this:
/api/v1/travels/{slug}/tours?priceFrom=123&priceTo=456&dateFrom=2023-06-01&dateTo=2023-07-01
So, we have four possible parameters:
- priceFrom
- priceTo
- dateFrom
- dateTo
And all of them are optional, so there may be only one of them passed, or all four.
So, our goal is to build a dynamic query based on different request()
parameters.
We will add a Request $request
parameter, which will be auto-resolved by Laravel and contain all the GET parameters.
And then, we will use the Eloquent method when()
, which has two parameters:
- a condition
- and how to transform the query in case of that condition is
true
use Illuminate\Http\Request; class TourController extends Controller{ public function index(Travel $travel, Request $request) { $tours = $travel->tours() ->when($request->priceFrom, function ($query) use ($request) { $query->where('price', '>=', $request->priceFrom * 100); }) ->when($request->priceTo, function ($query) use ($request) { $query->where('price', '<=', $request->priceTo * 100); }) ->when($request->dateFrom, function ($query) use ($request) { $query->where('starting_date', '>=', $request->dateFrom); }) ->when($request->dateTo, function ($query) use ($request) { $query->where('starting_date', '<=', $request->dateTo); }) ->orderBy('starting_date') ->paginate(); return TourResource::collection($tours); }}
You can read more about the when()
method in...