有条件地构建 Eloquent 查询

Conditionally building an Eloquent query

背景

我正在使用 Laravel 的 Eloquent 作为我的 ORM。我正在创建一个 API 端点,它提供对具有多个属性(colormakestatus)的 Cars 的访问。

我的端点允许客户端通过这些属性的任何子集过滤 return 值,如果他们不提供任何属性,那么我将 return 一切。

问题

我想构建一个条件查询,它从 "all" 开始,并根据指定的参数缩小范围。这是我写的:

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 return 是数据库中所有汽车的列表。 但是,如果我指定(例如)0 的状态,那么 API return 是一个空集,尽管有些汽车的状态是 0

我是不是处理错了?我缺少什么基本的东西吗?

请注意,如果我改为:

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

正确生成汽车列表

为了简单起见,您可以试试这个。

$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 的功能。

您应该像这样更改函数:

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