In the new Laravel Resource classes, you are able to remove attributes based on anything you like.
If you want to return many items, you can use the function
Resource::collection()
But that does not let you add metadata in one place. Enter a Collection, great, this is many items in a nice format with the ability to add meta data. What you cannot do though, is filter the collection you have to hide attributes like you can with a resource. The only way I can see to do it is
foreach ($this->collection as $item) {
if ($notAdmin) {
$temp = array_except($item->toArray(), ['secret']);
}
$temp['links'] = ['self' => route('restaurant.show', [$item])];
$data[] = $temp;
}
Is there something I am missing? This seems like a massive overlooked ability for a Resource Collection
Based in this thread, it seems that when using a ResourceCollection class to customize a collection (for example BookCollection
) Laravel look up for a Resource class named the same but without the Collection sufix class (in the example, a class named just Book
).
So you will need to have a resource class named: Book
where you customize the attributes to be returned to the response and a collection class named: BookCollection
, that will use Book
-to customize the data- and will also let you customize the metadata.
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\Resource;
class Book extends Resource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
];
}
}
<?php
namespace App\Http\Resources\Users;
use Illuminate\Http\Resources\Json\ResourceCollection;
class BookCollection extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request
* @return array
*/
public function toArray($request)
{
return $this->collection;
}
public function with($request)
{
return [
'meta' => [
'key' => 'value',
],
];
}
}
Ok, here's how you do it:
Create a Resource
for a single resource, where you can easily have conditional attributes
Create a RCollection
for the collection, where you can add meta data .
Pass the Resource::collection(Model::all)
into the new RCollection()
.
Something like this (from my testing):
Route::get('users/all', function() {
return new \App\Http\Resources\Users(
\App\Http\Resources\UserResource::collection(\App\User::get())
);
});
Works like a charm!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.