【问题标题】:What will the best solution for this multiple optional filter?这个多重可选过滤器的最佳解决方案是什么?
【发布时间】:2022-04-17 16:00:41
【问题描述】:

这些都是可选字段,所以我是否必须编写多个带有条件的查询,或者有什么方法可以使用 Laravel 来处理这个问题?查询会是什么样子?

谢谢

【问题讨论】:

标签: php mysql laravel laravel-5


【解决方案1】:

这在一定程度上取决于过滤器的提交方式,但您可以执行以下两件事之一(可能还有更多......):

public function listCars(Request $request)
{
    $cars = Car::when($request->get('make'), function ($query, $make) {
            $query->where('make', $make);
        })
        ->when($request->get('model'), function ($query, $model) {
            $query->where('model', $model);
        })
        ->...
        ->get();

    // do what you have to do
}

因此,您基本上将查询构建器调用包装在when($value, $callback) 中,如果$value 评估为真,它将仅执行$callback。当您使用$request->get('parameter') 检索未设置的参数时,它将返回 null 并且不会执行回调。但要小心,如果$value0 它也不会执行回调。所以请确保您没有将其作为索引。

除此之外,您也可以做同样的事情,但表达方式要少一些...

public function listCars(Request $request)
{
    $query = Car::query();

    if($request->filled('make')) {
        $query->where('make', $request->get('make'));
    }
    if($request->filled('model')) {
        $query->where('model', $request->get('model'));
    }

    // some more filtering, sorting, ... here

    $cars = $query->get();

    // do what you have to do
}

【讨论】:

  • 这是有效的,但今年,引擎在关系表“模型”中,例如:我可以通过 $vehicel->models[0]->engine, $vehicel- >模型[1]->引擎。如果我通过直接年份或引擎,它会给我列未找到错误
  • 您的描述确实没有任何意义,但听起来也与这个问题无关。您要求一种设计过滤器的好方法,而不是如何对过滤器本身进行编码。也许为过滤器本身打开一个新问题,详细描述您的表、关系等。
  • 谢谢!有效!我的情况有点不同,但你的回答帮助我弄清楚了。
【解决方案2】:

这是我在我的应用程序中进行的类似查询的工作示例。

   $filters = $vehicle->newQuery();

    if (!empty($request->make)) {
        $filters->where('make_id', $request->make);

    }
    if (!empty($request->carmodel)) {
        $filters->where('carmodel_di', $request->carmodel);

    }
    if (!empty($request->year)) {
        $filters->where('year_id', $request->year);

    }
    if (!empty($request->engine)) {
        $filters->where('engine_id', $request->engine);

    }

    if (!empty($request->price)) {
        $filters->where('price_id', $request->price);

    }

    $cars = $filters->latest()->paginate(50);

现在推送 $cars 变量以查看。我希望这对你有用,或者至少让你知道如何继续

【讨论】:

  • 你的代码可以运行,但是如果你使用 Laravel,Namoshek 和 akramwasim 方法是完美的。
【解决方案3】:

这里有一个简单的方法,你也可以在 ->when() 条件内设置条件连接,如果你在 Laravel 版本 > 5.4,使用 $request>filled() 而不是 $request->has()

    public function listCars(Request $request)
{
    $cars = Car::when($request->has('make'), function ($query)use($request) {
            $query->join('maker','car.makerId','=','maker.id')
            ->where('make', $request->input('make'));
        })
        ->when($request->has('model'), function ($query)use($request) {
            $query->where('model', $request->input('model'));
        })
        ->...
        ->get();

    // you can even make the join conditionaly, 
}

【讨论】:

    【解决方案4】:
    $fiterItem = ['make','model','year','engine','price'];
    $filters = $vehicle->newQuery();
    
    foreach ($filter as $item) {
        if ($r->filled($item)) {
          $list->where($item, $r->query($item));
        }
    }
    $list = $filters->paginate(20);
    

    【讨论】:

    • 请记住,Stack Overflow 不仅仅是为了解决眼前的问题,而是为了帮助未来的读者找到类似问题的解决方案,这需要了解底层代码。这对于我们社区的初学者和不熟悉语法的成员来说尤其重要。鉴于此,您能否edit 您的答案包括对您正在做什么的解释以及为什么您认为这是最好的方法?
    猜你喜欢
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多