I have this long query builder where I am basically searching a table and then filter the results based on the passed query strings:
$projects = Listing::query()
->when(request('q'), function($builder) {
$builder->searchQuery(request('q'));
})
->when(request('tags'), function($builder) {
$tags = request('tags');
$builder->whereHas('tags', function($builder) use ($tags) {
$builder->whereIn('name', $tags);
});
})
->when(request('categories'), function($builder) {
$categories = request('categories');
$builder->whereHas('categories', function($builder) use ($categories) {
$builder->whereIn('name', $categories);
});
})
->when(request('countries'), function($builder) {
$countries = request('countries');
$builder->when(count($countries),function ($builder) use ($countries) {
$builder->whereHas('location', function($builder) use ($countries) {
$builder->where( function($builder) use ($countries) {
foreach ($countries as $country) {
$builder->orWhere('country', 'LIKE', '%' . $country . '%');
//$builder->orWhere('name', 'LIKE', '%' . $country . '%');
}
});
});
});
})
->when(request('opensource'), function($builder) {
$builder->where('open_source', request('opensource'));
})
->when(request('types'), function($builder) {
$types = request('types');
if (in_array("Other", $types)) {
$key = array_search("Other", $types);
$types[$key] = NULL;
$builder->whereIn('type', $types)->orWhereNull('type');
} else {
$builder->whereIn('type', $types);
}
})
->when(request('organizationtypes'), function($builder) {
$organizationtypes = request('organizationtypes');
if (in_array("Other", $organizationtypes)) {
$key = array_search("Other", $organizationtypes);
$organizationtypes[$key] = NULL;
$builder->whereIn('organization_type', $organizationtypes)->orWhereNull('organization_type');
} else {
$builder->whereIn('organization_type', $organizationtypes);
}
})
->when(request('status'), function($builder) {
$status = request('status');
if ($status == "Show active projects only") {
$builder->whereIn('status', ['Active', 'N/A']);
} else {
$builder = $builder;
}
})
->orderBy('created', 'DESC')
->paginate(50);
The query works well, however, my issue is with this part:
$status = request('status');
if ($status == "Show active projects only") {
$builder->whereIn('status', ['Active', 'N/A']);
} else {
$builder = $builder;
}
I would like if $status == "Show active projects only", then to show projects whose status is "Active", "N/A" and null. However when I modify the if part to:
$builder->whereIn('status', ['Active', 'N/A'])->orWhereNull('status');
I get wrong results. What am I doing wrong?
>Solution :
Try to enclose the whereIn() and the orWhereNull() in another where.
I’m quesing the orWhereNull() expands wider than the limitation within the status.
->when(request('status'), function($builder) {
$status = request('status');
if ($status == "Show active projects only") {
$builder->where(function($query) {
return $query->whereIn('status', ['Active', 'N/A'])
->orWhereNull('status');
});
}
// This doesn't do anything, so this can be removed
// else {
// $builder = $builder;
// }
})