Hiding fields in API Resources Using Gates in Laravel

381 Views Asked by At

I have a Product API resource in my application like so

    /**
     * Transform the resource collection into an array.
     *
     * @param  Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'desc' => $this->desc,
            'color' => $this->color,
            'amount' => $this->amount,
            'available' => $this->available,
            'createdAt' => $this->created_at,
            'updatedAt' => $this->updated_at,
        ];
    }

I have few roles in my application, like admin, viewer. When admin access the api, the api returns all fields but when the viewer access the api it returns only limited fields.

How can I handle this using Gates & Policies?

Can I do something like this

'createdAt' => $this->when($this->authorize('product.list'), $this->created_at)

1

There are 1 best solutions below

0
On

You could use an Eloquent Accessor in your Product model:

    public function getCreatedAtAttribute($createdAt)
    {
        if (Gate::allows('see-product-details', $this)) {
            return $createdAt;
        } else {
            return null;
        }
    }

Of course you also have to write the see-product-details gate.

Otherwise this may work as well (not tested):

    public function getCreatedAtAttribute($createdAt)
    {
        if ($this->authorize('view', [Product::class, $this])) {
            return $createdAt;
        } else {
            return null;
        }
    }