I'm trying to filter my products according to price, using a form in the view, I'm passing from and to as two separate filters and stuck from there. here's the code in my Product Model:
public function scopeFilter($query, array $filters)
{
$query->when(
$filters['from'] ?? false,
function ($query,$request) {
$query->whereBetween('price', [$request->from,$request->to]);
}
);
}
obviously this isn't working and when I dd the request it's giving me the "from" value only. any ideas?? this is my product controller:
public function index()
{
$categories = Category::get();
$products = Product::latest()->filter(request(['category','from','to']))->simplePaginate(5);
return view('welcome',compact('products','categories',));
}
at the moment it's giving me an error of "Trying to get property 'to' of non-object"
CodePudding user response:
You are reading the request wrong, Your scope filter function should be like:
public function scopeFilter($query, array $filters)
{
$query->when(
($filters['from'] && $filters['to']) ?? false,
function ($query) use ($filters){
$query->whereBetween('price', [$filters['from'],$filters['to']]);
}
);
}
CodePudding user response:
At the minute, you're just passing the from
price to the closure.
When you use when(), the first argument is passed as the second param of the closure (in this case the from
price...false
won't trigger the closure).
You can either add a use
statement to the closure:
public function scopeFilter($query, array $filters)
{
$query->when(
$filters['from'] ?? false,
function ($query) use ($filters) {
$query->whereBetween('price', [$filters['from'], $filters['to']]);
}
);
}
or, if you're using php >= 7.4
, you can use an arrow function instead:
public function scopeFilter($query, array $filters)
{
$query->when(
$filters['from'] ?? false,
fn ($query) => $query->whereBetween('price', [$filters['from'], $filters['to']]);
);
}
Furthermore, it would probably make more sense to remove the when
entirely as you should really be validating the values in your controller.