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

brakkar's avatar

Complex eloquent query doesn't behave properly

Hello, here is the query:

Topic::with( [ 'user', 'topicCategory', 'tagLanguage', 'tagEnvironment' ] )
     ->when( $selectedLanguageTagIds,  fn( $query ) => $query->whereHas( 'tagLanguage',                                                      fn( $q ) => $q->whereIn( 'id', $selectedLanguageTagIds ) ) )
     ->when( $selectedEnvironmentTagIds, fn( $query ) => $query->orWhereHas( 'tagEnvironment', fn( $q ) => $q->whereIn( 'id', $selectedEnvironmentTagIds ) ) )
     ->when( $CheckArray, fn( $query ) => $query->where( check_topic', '=', 1 ) )
                                                     ->get(),

This query is supposed to return any result that match:

( (tagLanguage OR tagEnvironment) AND CheckArray ) so anything from first or second when querries, AND from those, those that match the forth when query.

What would be the proper way to reformat this query?

0 likes
2 replies
tykus's avatar
tykus
Best Answer
Level 104

Logically grouping the when constraints will give you the expected query:

Topic::with( [ 'user', 'topicCategory', 'tagLanguage', 'tagEnvironment' ] )
    ->where(function ($builder) {
        $builder
            ->when($selectedLanguageTagIds,  fn($query) => $query->whereHas('tagLanguage', fn($q) => $q->whereIn( 'id', $selectedLanguageTagIds)))
            ->when($selectedEnvironmentTagIds, fn($query) => $query->orWhereHas('tagEnvironment', fn($q) => $q->whereIn( 'id', $selectedEnvironmentTagIds)));
    })
    ->when( $CheckArray, fn( $query ) => $query->where('check_topic', '=', 1))
    ->get()
1 like

Please or to participate in this conversation.