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

Uladzimir's avatar

How to join the requests in one?

How can I join these requests in one block so that they are in the same query? Unfortunately my variant don't work and show error undefined $films. In individual requests work correctly.

Here is their controller:

`public function show(Request $request, Film $film): View { $tags = $request->tags;

    if ($request->filled('tags')) {
        $films = Film::query()
            ->whereHas(
                'tags',
                fn ($query) => $query->whereIn('id', $tags),
                '=',
                count($tags)
            );
    } //this request searches among tags

    if ($request->filled(['genre', 'actors', 'year', 'age', 'director', 'time', 'country'])) {
        $films = $film->getFilmBySearch($request);
    } //this request searches among genre, actors, year, age, director, time, country

    $films = $films->paginate(20)->withQueryString();

    return view('films.tagresult', [
        'films' => $films
    ]);
}`
0 likes
3 replies
tykus's avatar

You can use the when Builder method to conditionally add constraints:

public function show(Request $request, Film $film): View
{
    $tags = $request->tags;
    $films = Film::query()
        ->when($request->get('tags'), function ($builder, $tags) {
            $builder->whereHas('tags', fn ($query) => $query->whereIn('id', $tags), '=', count($tags));
        })
        ->when($request->filled(['genre', 'actors', 'year', 'age', 'director', 'time', 'country']), function ($builder) use ($request) {
             $builder->getFilmBySearch($request);
        })
        ->paginate(20)
        ->withQueryString();

    return view('films.tagresult', ['films' => $films]);
}
Uladzimir's avatar

@tykus thank you! unfortunately there is an error on first block count(): Argument #1 ($value) must be of type Countable|array, bool given

here:

$builder->whereHas('tags', fn ($query) => $query->whereIn('id', $tags), '=', count($tags));

and on getFilmBySearch($request); wrote that $request undefined variable. May be I where mistaked? Because eloquent model and query builder can intersect here

tykus's avatar
tykus
Best Answer
Level 104

@Uladzimir yeah, that requires (i) the get rather than filled method to ensure the Closure gets the value of tags rather than the result of filled

->when($request->get('tags'), function ($builder, $tags) {
    $builder->whereHas('tags', fn ($query) => $query->whereIn('id', $tags), '=', count($tags));
})

and (ii) the request variable to be passed into the Closure scope:

->when($request->filled(['genre', 'actors', 'year', 'age', 'director', 'time', 'country']), function ($builder) use ($request) 
    $builder->getFilmBySearch($request);
})

Fixed both above

1 like

Please or to participate in this conversation.