4

I am working on an API that will be accessible via a mobile and web app.
I need to send specific fields from the API resource.

I have ItemResource

public function toArray($request) {
    return [
        'id'          => $this->id,
        'name'        => $this->name,
        'description' => $this->description,
        'price'       => $this->price,
        'stock'       => $this->stock,
        'reviews'     => $this->reviews, // this is from reviews table
    ];
}

My Item Model

public function reviews() {
    return $this->hasMany(ItemReview::class);
}

My controller code

return ItemResource::collection(Item::all());

I get this array

{
    "data": {
        "id": 10,
        "name": "Item Name",
        "description": "Item description",
        "price": 410,
        "stock": "815",
        "reviews": [
            {
                "id": 4,       // I don't want to get this field
                "item_id": 10, // I don't want to get this field
                "user_id": 9,  // I want to show user name instead of user id
                "review": "item review."
            },
            {
                "id": 12,      // I don't want to get this field
                "item_id": 10, // I don't want to get this field
                "user_id": 3,  // I want to show user name instead of user id
                "review": "item review."
            }
        ]
    }
}

I want to get an array like this

{
    "data": {
        "id": 10,
        "name": "Item Name",
        "description": "Item description",
        "price": 410,
        "stock": "815",
        "reviews": [
            {
                "user_name": 'jhon',  
                "review": "item review."
            },
            {
                "user_name": 'jhon2',  
                "review": "item review."
            }
        ]
    }
}

I would like to show only specific fields.
How can I implement this?

1 Answer 1

6

1. Only select what you need

If you add parentheses after reviews, you can return a Builder instance, which will allow you to add queries to the relationship.
With this, you can select the fields you need.

public function toArray($request) {
    return [
        'id'          => $this->id,
        'name'        => $this->name,
        'description' => $this->description,
        'price'       => $this->price,
        'stock'       => $this->stock,
        'reviews'     => $this->reviews()->select('user_name', 'review')->get(),
    ];
}

2. Create a ReviewResource

You can also create a resource for Review that returns it's own data.

class ReviewResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'user_name' => $this->user_name,
            'review' => $this->review,
        ];
    }
}
class ItemResource extends JsonResource
{
    public function toArray($request) {
        return [
            'id'          => $this->id,
            'name'        => $this->name,
            'description' => $this->description,
            'price'       => $this->price,
            'stock'       => $this->stock,
            'reviews'     => ReviewResource::collection($this->reviews),
        ];
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.