2

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',
        ];
    }
}
user7646471
  • 352
  • 3
  • 11

3 Answers3

2

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),
];
hungtran273
  • 1,180
  • 9
  • 11
1

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();
Leo
  • 7,274
  • 5
  • 26
  • 48
  • Thanks for your reply. Tested it and it does not have any effect. Just to be sure, loading of categories is not the issue. I just cannot reference it in my ResourceCollection. Like described here : https://laravel.com/docs/5.5/eloquent-resources#conditional-relationships – user7646471 Feb 07 '18 at 17:54
  • Normally a post belongs only to one category since the concept of categories is, that they are hierarchically. Otherwise they are tags. But lets go for the example: The relationships are correct in the question as you can read also in documentation https://laravel.com/docs/5.5/eloquent-relationships#many-to-many. Both ends are `belongsToMany` – common sense Feb 07 '18 at 21:04
0

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;
}
francisco
  • 1,387
  • 2
  • 12
  • 23
user7646471
  • 352
  • 3
  • 11