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

mriyadh's avatar

DataBase Query : return all results if field is null

With my app I have search function including 3 fields (cargov, carname, carmodel). I want my user to be able to select the fields that he wants for search so if the car name filed is not provided by the user ( null, same as for the car model filed ) the query should return all results, I tried the following and it's working only when providing all the fields but it doesn't work one is missing?

<?php 

namespace App\Http\Controllers;

use App\Car;
use Illuminate\Http\Request;
class ByNameController extends Controller
{
    
 
   public function list(Request $request){
        
        $carGov = $request->get('carGov');
        $carName = $request->get('carName');
        $carModel = $request->get('carModel');
       $car_list = Car::select('cargov', 'carname', 'carmodel');
       $car_list = is_null($carModel) ? $query : $car_list->wherecarmodel($carModel);
       $car_list = is_null($carName) ? $query : $car_list->wherecarname($carName);
       $result = $car_list->orderBy('updated_at','DESC')->paginate(10);
        return response()->json($result,200);
    }
  
}


?>
0 likes
13 replies
arukomp's avatar

You were assigning $query when null, but you should've assigned $car_list which is the original query you're building on.

   public function list(Request $request){
        
        $carGov = $request->get('carGov');
        $carName = $request->get('carName');
        $carModel = $request->get('carModel');
        $car_list = Car::select('cargov', 'carname', 'carmodel');
        $car_list = is_null($carModel) ? $car_list : $car_list->wherecarmodel($carModel);
        $car_list = is_null($carName) ? $car_list : $car_list->wherecarname($carName);
        $result = $car_list->orderBy('updated_at','DESC')->paginate(10);
        return response()->json($result,200);
    }
2 likes
mriyadh's avatar

but you should've assigned $car_list as you mentioned but its produce the same result ( empty list ) when car name, model is not provided. I'm testing with postman and when I don't provide carModel and return $carModel instead of car_list the result is ""

Snapey's avatar
Snapey
Best Answer
Level 122
   public function list(Request $request){
        
    $query = Car::select('cargov', 'carname', 'carmodel');

    if($request->filled('carGov') {
        $query->where('cargov', $request->carGov);
    }

    if($request->filled('carName') {
        $query->where('carname', $request->carName);
    }

    if($request->filled('carModel') {
        $query->where('carmodel', $request->carModel)
    }

        $result = $query->orderBy('updated_at','DESC')->paginate(10);

        return response()->json($result,200);
    }

Easier to follow

2 likes
Snapey's avatar

Is this your exact code? My original posting had a typo

1 like
skliche's avatar

@mriyadh If you prefer chaining

$result = Car::select('cargov', 'carname', 'carmodel')
    ->when($request->filled('carGov'), function($query) use ($request) {
        return $query->where('cargov', $request->carGov);
    })
    ->when($request->filled('carName'), function($query) use ($request) {
        return $query->where('carname', $request->carName);
    })
    ->when($request->filled('carModel'), function($query) use ($request) {
        return $query->where('carmodel', $request->carModel);
    })
    ->orderBy('updated_at','DESC')->paginate(10);

return response()->json($result, 200);
1 like
mriyadh's avatar

@Snapey How can i change below line to select all columns ? or i have to add them all

$query = Car::select('cargov', 'carname', 'carmodel');

Snapey's avatar

I think

$query = Car::select('*');

or

$query = Car::newQuery();
1 like
mriyadh's avatar

@Snapey Sorry for re posting but I'm facing a strange behavior with this code,

public function list(Request $request){
       
   $query = Car::select('cargov', 'carname', 'carmodel');

   if($request->filled('carGov') {
       $query->where('cargov', $request->carGov);
   }

   if($request->filled('carName') {
       $query->where('carname', $request->carName);
   }

   if($request->filled('carModel') {
       $query->where('carmodel', $request->carModel)
   }

       $result = $query->orderBy('updated_at','DESC')->paginate(10);

       return response()->json($result,200);
   }

As you can see I'm paging the result of my query ( 10 / Page ), the first page results matches the query successfully but starting from Page2 and so on the results will not match the query (exactly select all with out any conditions) ? any ideas why this is happening.

Snapey's avatar

you have to add the query terms back to the pagination link.

mriyadh's avatar

@Snapey Again I'm sorry for not being so clear I agree with you for passing the query terms but let me explain more .

my request response is like below,

{
    "current_page": 1,
    "data": [
        {
            // array of my object
        }
    ],
    "first_page_url": "https://www.example.com/Search?page=1",
    "from": 1,
    "last_page": 3,
    "last_page_url": "https://www.example.com/Search?page=3",
    "next_page_url": "https://www.example.com/Search?page=2",
    "path": "https://www.example.com/Search",
    "per_page": 10,
    "prev_page_url": null,
    "to": 10,
    "total": 27
}

The response is already provide the next page url which I use directly to fetch the next page and so on, When i use it with simple query like,

public function list(){
        
        $car_list = Car::where([['cargage', '>', 10000]])->orderBy('updated_at','DESC')->paginate(10);
        return response()->json($car_list,200);
    }

There is no need to pass the query terms with each page but it's loosing the terms only here

public function list(Request $request){
       
   $query = Car::select('cargov', 'carname', 'carmodel');

   if($request->filled('carGov') {
       $query->where('cargov', $request->carGov);
   }

   if($request->filled('carName') {
       $query->where('carname', $request->carName);
   }

   if($request->filled('carModel') {
       $query->where('carmodel', $request->carModel)
   }

       $result = $query->orderBy('updated_at','DESC')->paginate(10);

       return response()->json($result,200);
   }

Snapey's avatar

Yes, each page has no history of what went before.

So, your URL, instead of being

https://www.example.com/Search?page=2

it needs to be

https://www.example.com/Search?page=2&carModel=big&carName=fred

see https://www.example.com/Search?page=2

Look down to Appending To Pagination Links

You can do this in the controller before returning your json I think

1 like
shez1983's avatar

You should look for request when directive.. it simplifies the query even further ithink

Please or to participate in this conversation.