Laravel Eloquent – Filter Relationship of Relationship

This is the query I tried to do:

$products = Product::with(['cross_selling.product_related' => 
   fn($query) => $query->where('status_id', '=', '2')])

I get this results:

Laravel Eloquent - Filter Relationship of Relationship

In cross_selling I still get id:12 that doesn’t has any product_related. I need some help for making that the query doesn’t give me that item if product_related is null.



Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

First get only those cross selling which has any related products after that get related products. Use the whereHas condition on cross_selling.

$products = Product::with(['cross_selling' => function($qry){
    $qry->whereHas('product_related', function ($q) {
        $q->where('status_id', 2);
    }, 'cross_selling.product_related' =>
    fn($query) => $query->where('status_id', '=', '2')])

Method 2

Try this

$products = Product::with(['cross_selling.product_related' => 
   fn($query) => $query->where('status_id', '=', '2')])

Method 3

If you don’t want cross selling products with no related products you can add


Which basically says: Get me only cross selling which have ‘product_related’.

In order to do it properly, you can:

$callback = fn($query) => $query->where('status_id', 2);
$products = Product::whereHas('cross_selling.product_related', $callback)
->with(['cross_selling.product_related' => $callback])

Now the callback is applied to the whereHas() and the with() plus you can pass additional constraints using $callback.

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Notify of

Inline Feedbacks
View all comments
Would love your thoughts, please comment.x