Reputation: 13791
The Context
I'm using Laravel's Eloquent as my ORM. I am creating an API endpoint which provides access to Cars
which have several attributes (color
, make
, status
).
My endpoint allows clients to filter the return value by any subset of those attributes, if they provide no attributes then I will return everything.
The Question
I want to build a conditional query, which starts from "all" and narrows down based on which parameters have been specified. Here's what I've written:
public function getCars(Request $request)
{
$results = Cars::all();
if($request->has('color'))
$results = $results->where('color', $request->input('color'));
if($request->has('make'))
$results = $results->where('make', $request->input('make'));
if($request->has('status'))
$results = $results->where('status', $request->input('status'));
return $results->toJson();
}
If I call this with no parameters the API returns a list of all cars in the database.
If, however, I specify (for instance) status of 0
the API returns an empty set, despite the fact that some cars have status of 0
.
Am I approaching this incorrectly? Is there something fundamental I'm missing?
Note that if instead I write:
$results = Cars::where('status', 0);
return $results->get();
The list of cars is properly generated
Upvotes: 3
Views: 2940
Reputation: 50491
You could try this, for simplicity.
$query = Cars::query(); // no query executed, just give us a builder
$query->where(array_only($request->all(), ['color', 'make', 'status'])); // where can take a key value array to use
// update: only taking the vars you need, never trust incoming data
return $query->get(); // will be converted to Json for you
This only queries the DB for what you need. Yours is returning all results then filtering through them in a collection.
Update: As Joseph stated, there is different functionality between $request->only() and array_only. The functionality of array_only is wanted here.
Upvotes: 3
Reputation: 111859
You should change your function like this:
public function getCars(Request $request)
{
$results = Cars::query();
if($request->has('color'))
$results = $results->where('color', $request->input('color'));
if($request->has('make'))
$results = $results->where('make', $request->input('make'));
if($request->has('status'))
$results = $results->where('status', $request->input('status'));
return $results->get()->toJson();
}
Upvotes: 8