eloquent - 查询构建器中的动态和条件whereHas()

arv*_*vil 1 php laravel eloquent laravel-eloquent

我试图在我的查询构建器中避免DRY,特别是在链中添加其他方法.

例如,这最初是我的查询构建器:

$products = $app->myShop->realProducts()
        ->where($query)
        ->skip($skip)->take($take)
        ->orderBy($sortKey, $sortOrder)
        ->get();
Run Code Online (Sandbox Code Playgroud)

然后,如果用户使用了一些过滤器,我需要将一个方法(特别是a whereHas())附加到查询构建器

    $products = $app->myShop->realProducts()
        ->where($query)
        ->whereHas('colour', function ($q) use ($find) {
            $q->where('colour_slug', $find);
        })
        ->skip($skip)->take($take)
        ->orderBy($sortKey, $sortOrder)
        ->get();
Run Code Online (Sandbox Code Playgroud)

我觉得要实现这个结果"丑陋",我必须不断重复那些构建器查询:

if ($user_filtered_this_page == TRUE) {

    $products = $app->myShop->realProducts()->where($query)
        ->whereHas('colour', function ($q) use ($find) {
            $q->where('colour_slug', $find);
        })
        ->skip($skip)->take($take)
        ->orderBy($sortKey, $sortOrder)
        ->get();

} else {

    $products = $app->myShop->realProducts()->where($query)
        ->skip($skip)->take($take)
        ->orderBy($sortKey, $sortOrder)
        ->get();
}
Run Code Online (Sandbox Code Playgroud)

是否有更聪明或更优雅的方式动态和有条件地将whereHas()方法附加到链?

希望有人可以提供帮助.谢谢!

Jon*_*hon 8

在您调用之前,查询不会执行,->get()因此您可以非常简单地构建查询,有条件地添加您的查询->whereHas()然后执行它:

$query= $app->myShop->realProducts()
    ->where($query)
    ->skip($skip)->take($take)
    ->orderBy($sortKey, $sortOrder);

if (...) {
    $query->whereHas(...);
}

$products = $query->get();
Run Code Online (Sandbox Code Playgroud)