I would like to construct a series of eloquent WHERE clauses dependent on the search parameters I collect from a json object.
Something like this (never mind the syntax of object,,, it is an interpretation only to demonstrate):
$searchmap = "
{
"color": "red",
"height": "1",
"width": "2",
"weight": "",
"size": "",
}";
I then take the object and decode to get a search array...
$search = json_decode($searchmap, true);
If my weight and size are set to null or are an 'empty string' I would have eloquent code that looks like this..
$gadgets = Gadget::where('color', '=', $search['color'])
->where('height', '=', $search['height'])
->where('width', '=', $search['width'])
->paginate(9);
If they have a value then eloquent code would look like this..
$gadgets = Gadget::where('color', '=', $search['color'])
->where('height', '=', $search['height'])
->where('width', '=', $search['width'])
->where('weight', '=', $search['weight'])
->where('size', '=', $search['size'])
->paginate(9);
Is there a way to accomplish this dynamically.
I suppose the question should be ins there a way to chain eloquent where clauses dynamically based on a given parameter?
In a pseudo context I am looking to do something like this
$gadgets = Gadget::
foreach ($search as $key => $parameter) {
if ( $parameter <> '' ) {
->where($key, '=', $parameter)
}
}
->paginate(9);
Can chaining of where clauses be created in some way similar to this?
Thank you for taking the time to look at this!
UPDATE:
I also came up with something like this that seems to work well but i would like to welcome suggestions if improvement is a good idea.
$gadgets = New Gadget();
foreach ($search as $key => $parameter) {
if($parameter != ''){
$gadgets = $gadgets->where($key, '=', $parameter);
}
}
$gadgets = $gadgets->paginate(9);
FINAL
And thanks to @lukasgeiter below I think I will go with this
$gadgets = Gadget::whereNested(function($query) use ($search) {
foreach ($search as $key => $value)
{
if($value != ''){
$query->where($key, '=', $value);
}
}
}, 'and');
$gadgets = $gadgets->paginate(9);
That's easy. Laravel's
where
function allows you to pass in an array of key value pairs.If you are curious, that's the relevant part of the source (
\Illuminate\Database\Query\Builder
)Edit
To have more control over it (e.g. changing the "=" to another comparison operator) try using the code laravel uses internally directly:
For anyone who needs it, here's a modified version of lukasgeiter's answer that solves the 'variable number of wheres' problem while also allowing (1) different operators for each
where
clause and (2) the capacity to also usewhereIn
for when one of your "wheres" must be able to match one of multiple values (the function below detects when an array of values is passed and, thus, useswhereIn
instead ofwhere
).The
$paramSets
variable assignment at the beginning (below) essentially describes how to use it.