2

In my application there are users making pictures of items. The relationship structure is as follows:

Categories -> SubCategories -> Items -> Pictures -> Users

Now, there's also a shortcut relationship called itemPics between categories <--> pictures so that the number of pictures uploaded by a user can be quickly counted per category using withCount().

These are the relationships on the Category model:

public function subcategories() 
{
    return $this->hasMany('App\SubCategory');
}

public function items()
{
    return $this->hasManyThrough('App\Item', 'App\SubCategory');
}

public function itemPics()
{
    return $this->hasManyThrough('App\Item', 'App\SubCategory')
    ->join('pictures','items.id','=','pictures.item_id')
    ->select('pictures.*');
}

My problem is getting the number of pictures that a user has gathered per category. The itemPics_count column created by withCount() always has the same value as items_count, even though the number of related models for both relations given by with() are different in the JSON output.


        $authorPics = Category::with(['SubCategories', 'SubCategories.items' => function ($q) use ($author_id) {
                $q->with(['pictures' => function ($q) use ($author_id) {
                    $q->where('user_id', $author_id);
                }]);
            }])
        ->with('itemPics') /* added this to check related models in output */
        ->withCount(['items','itemPics'])
        ->get();
        dd($authorPics);

This does not make sense to me. Any help is greatly appreciated.

4
  • Might help showing the relationship methods in your model (specifically items and itemPics) Commented Aug 7, 2017 at 20:06
  • Relationships added. See edit. Commented Aug 8, 2017 at 6:15
  • 1
    withCount tracks until your relationship stop, it ignores join clause, are you try to get the number of pictures only? Commented Jan 24, 2020 at 3:56
  • 1
    withCount kicks in immediately with your select clause whereas with kicks in with another query, so your join clause will not be treated for withCount. Commented Jan 24, 2020 at 5:25

2 Answers 2

1

Withcount() function is not work properly if relations include join. it works only table to table relations.

    public function itemPics()
{
    return $this->hasManyThrough('App\Item', 'App\SubCategory')
    ->select('pictures.*');
}
Sign up to request clarification or add additional context in comments.

Comments

0

This solution was worked for me:

//...
public function itemPics()
{
    return $this->hasManyThrough('App\Item', 'App\SubCategory');
}

Then you can do something like this:

$authorPics = Category::with(['SubCategories', 'SubCategories.items' => function ($q) use ($author_id) {
      $q->with(['pictures' => function ($q) use ($author_id) {
         $q->where('user_id', $author_id);
      }]);
   }])
   ->with('itemPics') /* added this to check related models in output */
   ->withCount(['items','itemPics' => function($query){
      $query->join('pictures','items.id','=','pictures.item_id')
         ->select('pictures.*');
   }])
   ->get();
dd($authorPics);

Link to more information about Laravel withCount function here https://laravel.com/docs/8.x/eloquent-relationships#counting-related-models

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.