Home > Mobile >  laravel endpoint hide field
laravel endpoint hide field

Time:09-05

How can i hide some fields ? i want to hide the file field

Eloquent :

$reports = Report::select('id', 'file','company_id', 'title', 'year', 'created_at')
->orderBy('id', 'desc')
->paginate(10);

return ReportResource::collection($reports);

Model :

...
public function getFileSizeAttribute()
{
   return Storage::disk('files')->size($this->attributes['file']);
}
....

ReportResource:

...
public function toArray($request)
{
  return [
     'id' => $this->id,
     'title' => $this->title,
     'year' => $this->year,
     'views' => $this->whenNotNull($this->views),
     'file' => $this->whenNotNull($this->file), <-- i want to hide the file field
     'file_size' => $this->fileSize, <-- but always show file_size
     'created_at' => $this->created_at,
     'company' => new CompanyResource($this->company),
  ];
}

to get file_size field i must select the file field , because it's depends on it to calculate the file size.

but i want to hide the file field before send the response.

i know i can use the protected $hidden = [] method in the model , but i don't want that, because file field it's required on others place. i just want to hide it on this endpoint only.

CodePudding user response:

Since you are using API resources the best and clean way to do this is by using a Resource class for your collection. Said that, you will have 3 Resources:

The first one, as it is, just for retrieving a single Model with file and file_size attributes. The one you already have ReportResource.php

...
public function toArray($request)
{
  return [
     'id' => $this->id,
     'title' => $this->title,
     'year' => $this->year,
     'views' => $this->whenNotNull($this->views),
     'file' => $this->whenNotNull($this->file),
     'file_size' => $this->fileSize,
     'created_at' => $this->created_at,
     'company' => new CompanyResource($this->company),
  ];
}

A new second resource to be used in your endpoint, without the file attribute. IE: ReportIndexResource.php

...
public function toArray($request)
{
  return [
     'id' => $this->id,
     'title' => $this->title,
     'year' => $this->year,
     'views' => $this->whenNotNull($this->views),
     'file_size' => $this->fileSize,
     'created_at' => $this->created_at,
     'company' => new CompanyResource($this->company),
  ];
}

Now you need to create a Resource collection which explicitly defines the Model Resource to use. IE: ReportCollection.php

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class ReportCollection extends ResourceCollection
{
    /**
     * The resource that this resource collects.
     *
     * @var string
     */
    public $collects = ReportIndexResource::class;
}

Finally, use this new resource collection in your endpoint

$reports = Report::select('id', 'file','company_id', 'title', 'year', 'created_at')
->orderBy('id', 'desc')
->paginate(10);

return new ReportCollection($reports);

Of course, you can make use of makeHidden() method, but IMO is better to write a little more code and avoid a non desired attribute in your response because you forgot to make it hidden.

Also, in case you make use of makeHidden() method and you want to show the attribute in a future, you will have to update all your queries instead of a silgle resource file.

CodePudding user response:

If you want to make it Hide From All Returns , you can Do this in model

protected $hidden = ['file'];

and if you want to do it temporirly with this query , you can Use MakeHidden method

$users = $reports->makeHidden(['file']);

It's clear in laravel docs , take a look

https://laravel.com/docs/9.x/eloquent-collections#method-makeHidden

  • Related