Ahmed essam
Ahmed essam

Reputation: 357

Laravel customer API resource with relationships

Controller function:

public function index () {
    // TESTED
    // The getAllActiveSuppliers() function just return Supplier::pagniate(10)
    $suppliers = $this -> model -> getAllActiveSuppliers();
    return new SupplierResource($suppliers);
}

Returned Json:

    {
    "current_page": 1,
    "data": [
        {
            "id": 23,
            "name": "Test Name",
            "description": "Test Description",
            "created_by": {
                "id": 1,
                "name": "Test 1",
                "email": "[email protected]",
                "email_verified_at": null,
                "active": 1,
                "created_at": "2018-10-12 14:17:38",
                "updated_at": "2018-10-12 14:17:38"
            },
            "updated_by": {
                "id": 1,
                "name": "Test 1",
                "email": "[email protected]",
                "email_verified_at": null,
                "active": 1,
                "created_at": "2018-10-12 14:17:38",
                "updated_at": "2018-10-12 14:17:38"
            },
            "deleted_at": null,
            "created_at": "2018-10-31 01:46:11",
            "updated_at": "2018-11-02 22:05:14",

        }
    ],
    ...
}

What I am trying to do:

In the created_by and updated_by I just want to show name, email nothing else.

What I have tried to do:

I have tried to create an API resource collection

Supplier.php API Resource Collection :

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

Upvotes: 7

Views: 21479

Answers (3)

vimuth
vimuth

Reputation: 5612

Think we can add item to parent::toArray($request)

public function toArray($request)
    {
        $array = parent::toArray($request);
        $array['created_by'] = $this->created_by->only('name', 'email');
        return $array;
    }

Upvotes: 0

Bekim
Bekim

Reputation: 108

For anyone that may still need this as I was searching for myself in this topic

First create a resource for your relation with name, email fields

class UserResource extends JsonResource
{

    public function toArray($request)
    {
        return [
            'name' => $this->name,
            'email' => $this->email,
        ];
    }
}

Then create SupplierResource with relation created_by to User

class SupplierResource extends JsonResource
{

    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'description' => $this->description,
            'created_by' => new UserResource($this->created_by)
        ];
    }
}

In the Controller

public function index () {

    $suppliers = $this->model->getAllActiveSuppliers();
    
    return SupplierResource::collection($suppliers);
}

Upvotes: 3

Travis Britz
Travis Britz

Reputation: 5552

You first need to define a structure for a singular JsonResource object:

public function toArray($request)
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        ...
        'created_by' => $this->created_by->only('name', 'email'),
        ...
    ];
}

And then tell your ResourceCollection to use the class:

Customizing The Underlying Resource Class

Typically, the $this->collection property of a resource collection is automatically populated with the result of mapping each item of the collection to its singular resource class. The singular resource class is assumed to be the collection's class name without the trailing Collection string.

For example, UserCollection will attempt to map the given user instances into the User resource. To customize this behavior, you may override the $collects property of your resource collection

(From https://laravel.com/docs/5.7/eloquent-resources#concept-overview)

If your ResourceCollection doesn't do anything extra, you might not need it. Every JsonResource can transform itself for a collection with the collection() method, e.g. JsonResource::collection($models)

Upvotes: 1

Related Questions