Контекст
Я использую 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();
Список автомобилей сформирован правильно
Вы должны изменить свою функцию следующим образом:
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();
}
Вы можете попробовать это, для простоты.
$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 нужна здесь.