2

我试图在我的查询生成器中避免DRY,特别是在链中添加其他方法。

例如,这最初是我拥有的查询生成器:

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

然后,如果用户使用了一些过滤器,我需要将一个方法(特别是 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();

我觉得“丑陋”的是要达到这个结果,我必须不断重复那些构建器查询:

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

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

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

4

3 回答 3

11

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

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

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

$products = $query->get();
于 2017-02-18T19:19:04.343 回答
2

这可以使用查询生成器条件子句来完成

    $products = $app->myShop->realProducts()
        ->where($query)
        ->when($user_filtered_this_page, function($query) use($find){
            $query->whereHas('colour', function ($q) use ($find) {
                $q->where('colour_slug', $find);
            })
        })
        ->skip($skip)->take($take)
        ->orderBy($sortKey, $sortOrder)
        ->get();
于 2019-12-05T06:29:18.147 回答
2

你可以这样写:

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

希望对你有帮助;)

于 2017-02-18T19:17:05.850 回答