PiotrG
5 months ago

API Resource Related Model Filtering

Posted 5 months ago by PiotrG

Hello!

I am having trouble understanding how to filter a model resource relationship.

\Resources\User.php

<?php

namespace App\Http\Resources;

use App\Http\Resources\Termin as TerminResource;
use Illuminate\Http\Resources\Json\JsonResource;

class Benutzer extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->BENUTZER_KEY,
            'name' => $this->PERSON,
            'email' => $this->EMAIL,
            'username' => $this->BENUTZER,
            'password' => bcrypt($this->PASSWORT),
            'is_admin' => $this->SYSOP ? "true" : "false",
            'events' => TerminResource::collection($this->events)
        ];
    }
}

\Resources\Termin.php

<?php

namespace App\Http\Resources;

use Carbon\Carbon;
use Illuminate\Http\Resources\Json\JsonResource;

class Termin extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        // return parent::toArray($request);

        $start_date = Carbon::parse($this->TERMINE_VON_DAT)->format('Y-m-d');
        $start_time = Carbon::parse($this->TERMINE_VON_ZEI)->format('H:i');
        $start = Carbon::create($start_date . $start_time);

        $end_date = Carbon::parse($this->TERMINE_BIS_DAT)->format('Y-m-d');
        $end_time = Carbon::parse($this->TERMINE_BIS_ZEI)->format('H:i');
        $end = Carbon::create($end_date . $end_time);

        $allday = ($start == $end ? true : false);

        return [
            'id' => $this->TERMINE_KEY,
            'user' => $this->TERMINE_USER,
            'title' => $this->TERMINE_BETREFF ? $this->TERMINE_BETREFF : 'Kein Betreff',
            'location' => $this->TERMINE_ORT ? $this->TERMINE_ORT : 'Kein Ort',
            'start' => $start,
            'end' => $end,
            'allDay' => $allday,
            'category' => $this->TERMINE_CLASS ? $this->TERMINE_CLASS : 'Keine Kategorie',
        ];
    }
}

\Controllers\Api\BenutzerController.php

<?php

namespace App\Http\Controllers\Api;

use App\Benutzer;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Resources\Benutzer as BenutzerResource;
use App\Http\Resources\BenutzerCollection as BenutzerCollectionResource;

class BenutzerController extends Controller
{
    public function index()
    {
        return new BenutzerCollectionResource(Benutzer::paginate(100));
    }

    public function show(Benutzer $benutzer)
    {
        return new BenutzerResource($benutzer->with('events'));
    }
}

When accessing the

/api/benutzer/7

endpoint, I get the user and all their events.

Problem is that this returns ALL the events without any filtering or pagination and of course the query takes a very long time.

How would I go about adding filtering on the "events" relationship?

I would like to hit an endpoint like this /api/benutzer/7?include=events&filter[events.category]=Meeting

Please sign in or create an account to participate in this conversation.