Przejdź do treści

Laravel – AbstractPaginator

Przykład użycia AbstractPaginator, paginacja na kolekcji z funkcją “through” i strzałkowym callbackiem dla mapowania i redukowania.

Pomijam to że listowany kod kod nie robi “identycznie” tego samego ale zawsze zastanawiam się co jest bardziej czytelne po kilku latach jak trzeba dorobić jakiś dodatkowy filtr lub inny filter. A w tym czasie wersja Laravela urosła o 2 numerki.

AbstractPaginator to klasa która często jest zapominana, a jak dużo pracujesz z JavaSctiptem i REST API, to czasami jest to jedyne wyjście, żeby zachować filtrowania i mapowania ale nie rozwalić do reszty paginacji wyników.

$events = Event::query()
            ->where('reservations_limit', '>', 0)
            ->withCount('reservations')
            ->limit(3)
            ->paginate($request->input('per_page') ?? 2)
            ->withQueryString()
            ->through(fn($event) => [
                'id'=>$event->id,
                'title'=>$event->title
            ]);
{
    "current_page": 1,
    "data": [
        {
            "id": 1,
            "title": "Super wydarzenie 1"
        },
        {
            "id": 2,
            "title": "Konsultacje z Janae 17:00"
        }
    ],
    "first_page_url": "https://<HOST>/events?page=1",
    "from": 1,
    "last_page": 62,
    "last_page_url": "https://<HOST>/events?page=62",
    "links": [
        {
            "url": null,
            "label": "&laquo; Poprzednia",
            "active": false
        },
        {
            "url": "https://<HOST>/events?page=1",
            "label": "1",
            "active": true
        },
         ...
        {
            "url": "https://<HOST>/events?page=2",
            "label": "Następna &raquo;",
            "active": false
        }
    ],
    "next_page_url": "https://<HOST>/events?page=2",
    "path": "https://<HOST>/events",
    "per_page": 2,
    "prev_page_url": null,
    "to": 2,
    "total": 124
}

I standardowo

$events = Event::where('workspace_id', $workspace->id) 
            ->where('reservations_limit', '>', 0)
            ->withCount('reservations'); 
if ($request->has('place_id') && $request->input('place_id') > 0) {
            $events->where('place_id', $request->input('place_id'));
 }
$events = $events->paginate($request->input('per_page') ?? 2)->withQueryString(); 

return WorkspaceEventResource::collection($events);

Porównanie bardziej życiowego przypadku

Opcja 1

$events1 = Event::query()
            ->when($request->input('start'), function ($query,$start){
                $query->where('date_start','>=',Carbon::parse($start)->toDateTimeString());
            })
            ->when($request->input('end'), function ($query,$end){
                $query->where('end','<=',Carbon::parse($end)->toDateTimeString());
            })
            ->when($request->input('treatment_id'), function ($query,$treatment_id){
                $query->where('treatment_id',$treatment_id);
            })
            ->when($request->input('specialization_id'), function ($query,$specialization_id){
                $query->where('specialization_id',$specialization_id);
            })
            ->when($request->input('problem_id'), function ($query,$problem_id){
                $query->where('problem_id',$problem_id);
            })
            ->when($request->input('place_id'), function ($query,$place_id){
                $query->where('place_id',$place_id);
            })
            ->when($request->input('person_id'), function ($query,$person_id){
                $query->where('person_id',$person_id);
            })
            ->where('reservations_limit', '>', 0)
            ->withCount('reservations')
            ->paginate($request->input('per_page') ?? 2)
            ->withQueryString()
            ->through(fn($event) => [
                'id'=>$event->id,
                'title'=>$event->title
            ]);

return WorkspaceEventResource::collection($events1); 

Opcja 2

$date_start = $request->has('start') 
                    ? Carbon::parse($request->input('start')) 
                    : Carbon::now()->toDateTimeString();
$date_end = $request->has('end') 
                    ? Carbon::parse($request->input('end')) 
                    : Carbon::now()->addMonths(12)->endOfMonth();

$events = Event::where('workspace_id', $workspace->id)
            ->whereDate('date_start', '>=', $date_start)
            ->whereDate('date_end', '<=', $date_end)
            ->where('reservations_limit', '>', 0)
            ->withCount('reservations');

        if ($request->has('treatment_id') && $request->input('treatment_id') > 0) {
            $events->where('treatment_id', $request->input('treatment_id'));
        }
        if ($request->has('specialization_id') && $request->input('specialization_id') > 0) {
            $events->where('specialization_id', $request->input('specialization_id'));
        }

        if ($request->has('problem_id') && $request->input('problem_id') > 0) {
            $events->where('problem_id', $request->input('problem_id'));
        }

        if ($request->has('place_id') && $request->input('place_id') > 0) {
            $events->where('place_id', $request->input('place_id'));
        }
        if ($request->has('person_id') && $request->input('person_id') > 0) {
            $events->where('person_id', $request->input('person_id'));
        }

$events = $events->paginate($request->input('per_page') ?? 2)->withQueryString();

return WorkspaceEventResource::collection($events);