Условное построение Eloquent запроса

Контекст

Я использую Laravel’s красноречивый как мой ОРМ. Я создаю конечную точку API, которая обеспечивает доступ к Cars которые имеют несколько атрибутов (color, make, status).

Моя конечная точка позволяет клиентам фильтровать возвращаемое значение по любому подмножеству этих атрибутов, если они не предоставляют атрибутов, я все верну.

Вопрос

Я хочу построить условный запрос, который начинается с «все» и сужается в зависимости от того, какие параметры были указаны. Вот что я написал:

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();
}

Если я вызываю это без параметров, API возвращает список всех автомобилей в базе данных.
Если, однако, я указываю (например) статус 0 API возвращает пустой набор, несмотря на то, что некоторые автомобили имеют статус 0,

Я неправильно подхожу к этому? Есть что-то фундаментальное, что мне не хватает?

Обратите внимание, что если вместо этого я напишу:

$results = Cars::where('status', 0);
return $results->get();

Список автомобилей сформирован правильно

3

Решение

Вы должны изменить свою функцию следующим образом:

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();
}
6

Другие решения

Вы можете попробовать это, для простоты.

$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

Это только запрашивает БД о том, что вам нужно. Ваш возвращает все результаты, а затем фильтрует их в коллекции.

Обновить:
Как сказал Джозеф, между $ request-> only () и array_only существует разная функциональность. Функциональность array_only нужна здесь.

3

По вопросам рекламы [email protected]