laravel - Laravel 控制器 - 如何直接获取模型的查询对象?

下面的 Controller 方法根据激活的标志更改查询。

public function index(Request $request)
    {
        $q = new ProductModel();

        if($request->has('flag1')) {
            $q = $q->includeFlag1();
        }

        if($request->has('flag2')) {
            $q = $q->doFlag2();
        }

        if($request->has('flag3')) {
            $q = $q->doFlagthing3();
        }

        return $q->paginate();
    }

我见过的大多数示例代码都会从一开始就调用 where() 而不是创建一个新的 Model 实例,看起来像这样:

$q = ProductModel::where('available', true);
        if($request->has('flag1')) {
            $q->includeFlag1();
        }

但在我的情况下,基于 table 字段,我不可能从像这样的 where 开始,所以似乎我必须在每种情况下每次都做 $q = $q ......它不整洁,也不会做一些 hacky,比如尝试使用 where true 子句。

如何清理从一开始就整齐地获取查询对象并使用它,或者避免在每个 if() 中执行 $q = $q

回答1

您可以使用 query()when() 方法:

public function index(Request $request)
{
    $query = ProductModel::query()
        ->when($request->has('flag1'), function ($q) {
           $q->includeFlag1();
        })
        ->when($request->has('flag2'), function ($q) {
           $q->doFlag2();
        })
        ->when($request->has('flag3'), function ($q) {
           $q->doFlagthing3();
        })
        ->paginate();
}

官方文档在这里:https://laravel.com/docs/9.x/queries#conditional-clauses

有时您可能希望某些查询子句应用于基于另一个条件的查询。 (...) when 方法仅在第一个参数为真时执行给定的闭包。如果第一个参数为 false,则不会执行闭包。

您还有一个使用箭头函数的更简洁的替代方案(感谢@miken32 的评论):

public function index(Request $request)
{
    $query = ProductModel::query()
        ->when($request->has('flag1'), fn ($q) => $q->includeFlag1())
        ->when($request->has('flag2'), fn ($q) => $q->doFlag2())
        ->when($request->has('flag3'), fn ($q) => $q->doFlagthing3())
        ->paginate();
}

相似文章

最新文章