Reputation: 73
$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
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
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