demonz's avatar

loading relation in resource collection

hello , is this correct way to load relation 'organization' with resource collection ? it works but I don't know if it's bad practice https://github.com/Landish/pingcrm-react/blob/main/app/Http/Resources/ContactCollection.php

also for this he used get() before mapping , so I think it's not a good idea to select after getting the data ? https://github.com/Landish/pingcrm-react/blob/main/app/Http/Resources/OrganizationResource.php

Help please , and Lary "Quickdraw" A.I. Don't reply to this post

0 likes
5 replies
vincent15000's avatar

I do like this.

public function toArray($request)
{
    return parent::toArray($request);
}

And in the controller.

$rooms = new RoomCollection(
    Room::
        withCount('courses')
        ->orderBy('name')
        ->get()
);

And sure I have the JsonResource too.

public function toArray($request)
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        'can_update' => auth()->user()->can('update', $this->resource),
        'can_delete' => auth()->user()->can('delete', $this->resource),
    ];
}
demonz's avatar

@vincent15000 first code didn't work for me , I have this case

return Inertia::render('Program/Index', [
          'filters' => Request::all('search', 'trashed'),
          'programs' => new ProgramCollection(
              Program::with('courses')
                  ->orderBy('name')
                  ->filter(Request::only('search', 'trashed'))
                  ->paginate()
                  ->appends(Request::all())
          ),
      ]);

and also this

public function toArray($request)
{
  return parent::toArray($request);
}

but it didn't work so I solve it with this

 public function toArray($request)
  {
      return $this->collection->map->only(
          'id', 'name', 'hours', 'summary', 'courses'
      );
  }

is there other way than using $this->collection->map->only ?

1 like
vincent15000's avatar

@demonz Oh you are using InertiaJS.

Here is an example of how I use InertiaJS with collections and it works fine.

public function index()
{
    $this->authorize('viewAny', Room::class);
    $rooms = new RoomCollection(
        Room::
            withCount('courses')
            ->orderBy('name')
            ->get()
    );
    return Inertia::render('User/Rooms/Index', compact('rooms'));
}

To use this, you need to declare a RoomCollection to which you can add additional datas if you need and a RoomResource to write the fields you need to send to the frontend.

In your case it could be like this for the resource.

public function toArray($request)
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        'hours' => $this->hours,
        'summary' => $this->summary,
        'courses' => $this->courses,
    ];
}
1 like
demonz's avatar

@vincent15000 courses is not a column it's a relationship , the program has many courses

1 like
vincent15000's avatar

@demonz That's not a problem given that you load this relationships in the query.

Program::with('courses')->...

...

$courses = $program->courses; // this will give you the collection of courses binded to the program
1 like

Please or to participate in this conversation.