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

Melodia's avatar

Search query not working with min and max values

I have form with multiple search input fields, which min and max values are included. When I try to search all properties which min price is 450 000 I see nothing, but in my database I have properties that are 2 000 000. Also on the same note, If put 1 000 000 as max value It shows me properties that are even 2 000 000.

My search function in the controller:

public function search_page(PropertyFilters $filters)
{
   $properties =  Property::filter($filters)->paginate(9);

   return view('pages.search', compact('properties'));
 
}   

PropertyFilters.php:

public function city_suburb($city){
    if(!$city) {
       return $this->builder;
    } 
    return $this->builder->where('city', $city)->orWhere('suburb', $city);
}

public function type($type){
    if(!$type) {
       return $this->builder;
    } 
    return $this->builder->where('type', $type);
}

public function min_price($price){
    if(!$price) {
       return $this->builder;
    } 
    return $this->builder->where('price', '>=', $price);
}

 public function max_price($price){
    if(!$price) {
       return $this->builder;
    } 
    return $this->builder->where('price', '<=', $price);
}

public function bathrooms($bathrooms){
    if(!$bathrooms) {
       return $this->builder;
    }       
    return $this->builder->where('bathrooms', $bathrooms);
}

public function bedrooms($bedrooms){
    if(!$bedrooms) {
       return $this->builder;
    }       
    return $this->builder->where('bedrooms', $bedrooms);
}

QueryFilter.php

abstract class QueryFilter
{
    protected $request;
    protected $builder;

    public function __construct(Request $request){
        $this->request = $request;
    }

    public function apply(Builder $builder){
        $this->builder = $builder;

        foreach($this->filters() as $name => $value){
            if($value && method_exists($this, $name)){
                call_user_func_array([$this, $name], array_filter([$value]));
            }
        }
        return $this->builder;
    }

    public function filters(){
        return $this->request->all();
    }
}

Anything possibly done wrong in the logic?

0 likes
14 replies
D9705996's avatar

Could you post the full url you are using and/or any post data you are sending in the request

danhorton's avatar

I'm pretty sure you need to do something like this

Controller

public function search_page(PropertyFilters $filters)
{
   $properties =  $this->getProperties($filters)

   return view('pages.search', compact('properties'));
 
} 
...
    protected function getProperties(PropertyFilter $filters)
    {
        $bids = Property::filter($filters);
        
        return $bids->paginate(9);
    }  

PropertyFilters.php


class PropertyFilters extends Filters
{
    
    protected $filters = ['city_suburb', 'type', 'min_price', 'max_price', 'bathrooms', 'bedrooms'];

.... 
Snapey's avatar

install Laravel debugbar and check the SQL being generated

Melodia's avatar

@DANHORTON - I do not quite follow the answer. what do I do with the protected filters array?

is it possible to have a full snippet based on mine?

Melodia's avatar

@D9705996 - nothing regarding the price works...whether I filter in isolation or with both min and max price.And note that if I do this:

public function min_price($price){
Log::debug($price);
if(!$price) {
   return $this->builder;
} 
return $this->builder->where('price', '>=', $price);
}

I get the price in my log

danhorton's avatar

@MELODIA - Add as the first line in your PropertyFilters class with each of the function names as an element in the array

class PropertyFilters extends Filters
{
    
    protected $filters = ['city_suburb', 'type', 'min_price', 'max_price', 'bathrooms', 'bedrooms'];

public function city_suburb($city){
    if(!$city) {
       return $this->builder;
    } 
    return $this->builder->where('city', $city)->orWhere('suburb', $city);
}

public function type($type){
    if(!$type) {
       return $this->builder;
    } 
    return $this->builder->where('type', $type);
}
etc..
Melodia's avatar

@DANHORTON - If I follow your add-on logic, it still doesnt work.

For instance, I checked a property which min price is 1000000

http:/mydomain.com/search?city_suburb=&type=&min_price=1000000&max_price=&bedrooms=&bathrooms=

But the response shows me a properties which the price are even 500000 here is how my currently snippet looks like:

PropertyController.php

public function search_page(PropertyFilters $filters)
{
    $properties =  $this->getProperties($filters);

    return view('pages.search', compact('properties'));

} 

protected function getProperties(PropertyFilters $filters)
{
    $bids = Property::filter($filters);
    
    return $bids->paginate(9);
} 

PropertyFilters.php

protected $filters = ['city_suburb', 'type', 'min_price', 'max_price', 'bathrooms', 'bedrooms'];

public function city_suburb($city){
    if(!$city) {
       return $this->builder;
    } 
    return $this->builder->where('city', $city)->orWhere('suburb', $city);
}

public function type($type){
    if(!$type) {
       return $this->builder;
    } 
    return $this->builder->where('type', $type);
}

public function min_price($price){
    if(!$price) {
       return $this->builder;
    } 
    return $this->builder->where('price', '>=', $price);
}

 public function max_price($price){
    if(!$price) {
       return $this->builder;
    } 
    return $this->builder->where('price', '<=', $price);
}

public function bathrooms($bathrooms){
    if(!$bathrooms) {
       return $this->builder;
    }       
    return $this->builder->where('bathrooms', $bathrooms);
}

public function bedrooms($bedrooms){
    if(!$bedrooms) {
       return $this->builder;
    }       
    return $this->builder->where('bedrooms', $bedrooms);
}

Particularly for this line of code:

protected $filters = ['city_suburb', 'type', 'min_price', 'max_price', 'bathrooms', 'bedrooms'];

Why exactly do I have this array when I dont use the values? Because dont have min_price and max_price in the database.

Just trying to understand.

Melodia's avatar

@D9705996 - I am soring price as a string.

Now I search the following:

https://mydomain.com/search?city_suburb=&type=&min_price=&max_price=2000000&bedrooms=&bathrooms=

I am expecting to view all properties which the price does not exceed 2000000...but the result shows me properties that cost 2600000, 20000000 and more.

In a different attempt I tried this:

https://mydomain.com/search?city_suburb=&type=&min_price=450000&max_price=&bedrooms=&bathrooms=

The results page show nothing...but I am expecting to see all properties which the price is equal or greater than 450000

D9705996's avatar

It looks like you have you comparison operators the wrong way round

In min price you have return $this->builder->where('price', '>=', $price);

$a >= $b Greater than or equal to TRUE if $a is greater than or equal to $b.

I would also change you column to an integer instead of a string as it's a numeric value

Melodia's avatar

@d9705996 thinking of your last answer, I decided to alter my price data type to double, seeded some data and it seems like it works properly.

It happened that my price was a string type because I was using comma separation with javascript. Using double does not work.

Perhaps you would have an answer for that. Other than that we consider the question answered.

D9705996's avatar

It happened that my price was a string type because I was using comma separation with javascript. Using double does not work

Could you elaborate, what didn't work, what errors, etc can you share any relevant code

Please or to participate in this conversation.