Reputation: 199
I'm in a blog project. I have this API Resource for my Post model
return [
'id' => $this->id,
'title' => $this->title,
'body' => $this->body,
'date' => $this->date
];
but I don't want to get 'body' => $this->body
when I get collection of Posts, because I only use it when I want to show the post, not for listing them
How can I do that ? should I use Resource Collections ?
UPDATE:
makeHidden
should work, but it doesn't because we have Illuminate\Support\Collection
instead of Illuminate\Database\Eloquent\Collection
, how can I make a cast or make API resource's collection method to return an Illuminate\Database\Eloquent\Collection
instance ?
Upvotes: 2
Views: 5227
Reputation: 193
There is a method for conditionally adding attribute to resource as shown below
return [
'attribute' => $this->when(Auth::user()->isAdmin(), 'attribute-value'),
];
I hope this will help you
Upvotes: 1
Reputation: 783
I assume you have a PostResource
, if you don't you can generate one:
php artisan make:resource PostResource
Override the collection method on PostResource
and filter fields:
class PostResource extends Resource
{
protected $withoutFields = [];
public static function collection($resource)
{
return tap(new PostResourceCollection($resource), function ($collection) {
$collection->collects = __CLASS__;
});
}
// Set the keys that are supposed to be filtered out
public function hide(array $fields)
{
$this->withoutFields = $fields;
return $this;
}
// Remove the filtered keys.
protected function filterFields($array)
{
return collect($array)->forget($this->withoutFields)->toArray();
}
public function toArray($request)
{
return $this->filterFields([
'id' => $this->id,
'title' => $this->title,
'body' => $this->body,
'date' => $this->date
]);
}
}
You need to create a PostResourceCollection
php artisan make:resource --collection PostResourceCollection
Here the collection is being processed with the hidden field(s)
class PostResourceCollection extends ResourceCollection
{
protected $withoutFields = [];
// Transform the resource collection into an array.
public function toArray($request)
{
return $this->processCollection($request);
}
public function hide(array $fields)
{
$this->withoutFields = $fields;
return $this;
}
// Send fields to hide to UsersResource while processing the collection.
protected function processCollection($request)
{
return $this->collection->map(function (PostResource $resource) use ($request) {
return $resource->hide($this->withoutFields)->toArray($request);
})->all();
}
}
Now in PostController
you can call the hide
method with the field to be hidden:
public function index()
{
$posts = Post::all();
return PostResource::collection($posts)->hide(['body']);
}
You should get a collection of Posts without the body field.
Upvotes: 5