2

I'm trying to use Laravel's API Resources to handle some JSON and I'm not able to conditionally load a relationship, despite it being eager loaded.

My controller:

$games = Game::with('availableInterests')->get();

In my view, I'm json encoding the collection to be used in VueJS

games = @json(new \App\Http\Resources\GameCollection($games)),

GameCollection - unchanged from the class Laravel generated for me.

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class GameCollection extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return parent::toArray($request);
    }
}

GameResource

class GameResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'thumbnail_url' => $this->thumbnail_url,
            'available_interests' => Interest::collection($this->whenLoaded('availableInterests')),
        ];
    }
}

Game Model's Relationship

public function availableInterests() : BelongsToMany
{
    return $this->belongsToMany(Interest::class);
}

I've tried changing $this->whenLoaded('availableInterests') to $this->whenLoaded('available_interests') with no luck. I've double checked my spelling with no luck.

Why isn't this conditional relationship present in the json?

Even removing $this->whenLoaded() doesn't make this relationship appear.

5
  • Is this a duplicate? stackoverflow.com/questions/46421856/… Commented Mar 28, 2018 at 2:18
  • @scipilot I don't think so, given I'm already using with() to eager load the relationship Commented Mar 28, 2018 at 2:47
  • 2
    Have you made a resource class for Interest? What works for me in my API app is 'reviews' => ReviewResource::collection($this->whenLoaded('reviews')). Commented Mar 28, 2018 at 12:55
  • Do you get an error? As @ashraj98 said, 'available_interests' needs to be a resource. Looks like you are using the eloquent model Commented Mar 28, 2018 at 22:25
  • try to force eager loading in your Model $with = ['availableInterests']; Commented Mar 29, 2018 at 15:29

1 Answer 1

1
+100

I don't think you need GameCollection in this case.

I would try doing this:

InterestResource.php (create new class)

class InterestResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return parent::toArray($request);
        // or what ever array structure you want
    }
}

GameResource.php

class GameResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'thumbnail_url' => $this->thumbnail_url,
            'available_interests' => InterestResource::collection($this->whenLoaded('availableInterests')),
        ];
    }
}

Your Controller

$games = Game::with('availableInterests')->get();

Your View

games = @json(\App\Http\Resources\GameResource::collection($games)),
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.