user7646471
user7646471

Reputation: 372

Laravel API ResourceCollection WhenLoaded

I try to include a relationship in my resource array if it has been eager loaded, but don't get it working.

Anyone has an idea, how I can check the relationships in the ResourceCollection?

Database schema looks like this: enter image description here

Here is my Post Model

class Post extends Model
{
    function categories() {
        return $this->belongsToMany('App\Category');
    }
}

Here is my Category Model

class Category extends Model
{
    function posts() {
        return $this->belongsToMany('App\Post');
    }
}

Here is my Post Controller

Class PostController extends Controller
{
    public function index()
    {
        return new PostResourceCollection(Post::with("categories")->get());
    }
}

Here is my Post ResourceCollection

class PostResourceCollection extends ResourceCollection
{
    public function toArray($request)
    {

        return [
            'data' => $this->collection->transform(function($page){
                return [
                    'type' => 'posts',
                    'id' => $page->id,
                    'attributes'    => [
                        'name' => $page->title,
                    ],
                ];
            }),
            //'includes' => ($this->whenLoaded('categories')) ? 'true' : 'false',
            //'includes' => ($this->relationLoaded('categories')) ? 'true' : 'false',
        ];
    }
}

Upvotes: 2

Views: 4882

Answers (3)

user7646471
user7646471

Reputation: 372

got it.. That was the missing piece. if anyone has a better solution for this it would be much appreciated.

foreach ($this->collection as $item) {
  if ($item->relationLoaded('categories')) {
    $included = true;
}

Upvotes: 0

hungtran273
hungtran273

Reputation: 1355

Maybe too late, below solution is a workaround for this case:

return [
    ...,
    'includes' => $this->whenLoaded('categories', true),
];

Loading custom attribute:

return [
    ...,
    'includes' => $this->whenLoaded('categories', fn() => $this->categories->name),
];

Upvotes: 3

Leo
Leo

Reputation: 7420

You relationship is wrong, a post belongs to many categories while a category has many posts so change:

class Category extends Model
{
    function posts() {
        return $this->belongsToMany('App\Post', 'category_post');
    }
}

to

class Category extends Model
{
    function posts() {
        return $this->hasMany('App\Post', 'category_post');
    }
}

Now when you load the post you can load the categories also:

$posts = Post::with('categories')->get();

Upvotes: 1

Related Questions