A4family
A4family

Reputation: 73

How to get only the searched data with where clause?


    $data['ads'] = PostAd::where('category_id',$id)      
        ->orwhere('district_id','LIKE','%'.$location.'%')
        ->orWhere('condition','LIKE','%'.$condition.'%')
        ->orWhere('price','>='.$min_price)
        ->orWhere('price','<='.$max_price)   
        ->orWhere('fuel',$fuel)
        ->orWhere('anchalorpradesh',$anchal)
        ->orWhere('mileage',$mileage)
        ->orWhere('kilometers',$kilometers)
        ->orWhere('engine',$engine) 
        ->get();

i want to show data whose category_id is $id. But whenever i try to search it shows me all the data in the database. Suppose i want to search data whose kilometer is 24. There is only one data whose kilometer is 24. But instead of showing that one data it shows me all the data in database.

Upvotes: 0

Views: 44

Answers (2)

Martin Bean
Martin Bean

Reputation: 39439

You can use the when method to conditionally add clauses to your queries depending on a value passing a “truth” test:

PostAd::query()
    ->when($request->get('category_id'), function ($query, $categoryId) {
        $query->where('category_id', '=', $categoryId);
    })
    ->paginate();

The closure you pass as the second argument will receive two arguments: a query builder instance that you can modify, and the value you passed as the first parameter to the when method.


You can also take this one step further and move your filtering logic to a dedicated class:

class PostAdFilters
{
    protected $request;
    protected $builder;

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

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

        foreach ($this->request->query() as $key => $value) {
            // Convert something like `category_id` to `filterByCategoryId`
            $methodName = 'filterBy' . Str::studly($key);

            if (method_exists($this, $methodName)) {
                // If the method exists, call it
                call_user_func([$this, $methodName], $value);
            }
        }

        // Return the modified query builder
        return $this->builder;
    }

    private function filterByCategoryId($value)
    {
        $this->builder->where('category_id', '=', $value);
    }

    private function filterByKilometers($value)
    {
        $this->builder->where('kilometers', '=', $value);
    }

    // And so on...
}

class PostAd extends Model
{
    public function scopeFilters(Builder $query, PostAdFilters $filters)
    {
        return $filters->apply($query);
    }
}

You can then inject this class in your controller method, and apply it to your model:

public function search(PostAdFilters $filters)
{
    return PostAd::filter($filters)->paginate();
}

This approach is based on https://laracasts.com/series/eloquent-techniques/episodes/4

Upvotes: 1

Prafulla Kumar Sahu
Prafulla Kumar Sahu

Reputation: 9703

Try something like this, adding conditional optionally based on search parameters choosen

$query = PostAd::query();

if ( isset($id) ) {
    $query = $query->where('category_id',$id);
}

if ( isset($location) ) {
    $query = $query->where('district_id', 'LIKE', '%' . $location . '%');
}

if ( isset($condition) ) {
    $query = $query->where('condition', 'LIKE', '%' . $condition. '%');
}

$result = $query->get();

Upvotes: 1

Related Questions