Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

janhaehl's avatar

Query distant (many to many) relationship

Hey folks, I'm stuck with the following. I am building a query based on a filter from a form. One dimension that I need to filter for, is a distant relationship.

Here's the concrete example: I'm having posts and cuisine, every posts has one or multiple cuisines (and thus also vice versa). cuisine and post are connected using a pivot table cuisine_post.

in my cuisine.php:

    public function posts()
    {
        return $this->belongsToMany(post::class);
    }

In my post.php:

    public function cuisines()
    {
        return $this->belongsToMany(cuisine::class);
    }

Thus, I can successfully access post->cuisines and vice versa.

Now in my query, I need to return a collection of post objects that have certain cuisines. Cuisines are selected using checkboxes on the filter, return values are the respective cuisine_id.

How do I now filter my posts to certain cuisines?

Btw, here's the rest of the filter query (which works fine), with cuisine still missing.

        $posts = post
        ::when($request->get('pricerange'), function($query) use($request) {
            $query->whereIn('pricerange',$request->get('pricerange'));
        })
        ->when($request->get('is_vegan'), function($query) {
            $query->where('is_vegan',true);
        })
        ->when($request->get('is_date'), function($query) {
            $query->where('is_date',true);
        })
        ->when($request->get('is_delivery'), function($query) {
            $query->whereNotNull('url_delivery');
        })
        ->when($request->get('is_menu'), function($query) {
            $query->whereNotNull('url_menu');
        })
        ->paginate(5);

Thanks for your help!

0 likes
3 replies
bobbybouwmann's avatar
Level 88

You can simply use has or whereHas do something like this

$cuisines = $request->get('cuisines');

Post::whereHas('cuisines', function ($query) use ($cuisines) {
    return $query->whereIn('cuisine_id', $cuisines);
})->when($request->get('pricerange'), function($query) use($request) {
    return $query->whereIn('pricerange',$request->get('pricerange'));
})
// Add more filters here
->paginate(5);

Well you get the basic idea. More on this topic can be found in the docs

Documentation: https://laravel.com/docs/5.8/eloquent-relationships#querying-relationship-existence

1 like
Snapey's avatar

Sounds like you need multiple orWhereHas. Iterate over your selected cuisines adding a orWhereHas for each.

1 like

Please or to participate in this conversation.