Laravel动态哪里有

时间:2019-04-09 16:41:23

标签: php eloquent

我正在尝试通过关系路径运行查询。以人类可读的格式:

Get collection of orders where $order->orderItem->product->sku is LIKE 'red-jumper';

我可以使用whereHas查询手动创建此文件,如下所示:

$query->whereHas('orderItems', function($query) use($request){
    $query->whereHas('product', function ($query) use($request){
        $query->where('sku', 'LIKE', '%' . $request->search . '%');
    });
});

但是,如果我希望它是动态的并且不知道关系中的级别数,我该怎么做?

我会寻找喜欢的东西:

$paths = [
0 => 'orderItems'
1 => 'product,
2 => 'sku'
];

$query->whereHas($paths[0], function($query) use($request, $paths){
    $query->whereHas($paths[1], function ($query) use($request, $paths){
        $query->whereHas($paths[2], function ($query) use($request, $paths) {
            $query->whereHas($paths[3], function ($query) use ($request, $paths) {
                $query->where('sku', 'LIKE', '%' . $request->search . '%');
            });
        });
    });
});

也许有更好的方法可以一起完成这些操作?

1 个答案:

答案 0 :(得分:1)

我认为有一种更好的方法。您可以对关系和集合使用点(。)表示法将$ path数组转换为所需的形式。首先,我们将$ path简化为点状关系,并在以后分隔要过滤的属性

$path = ['orderItems', 'product', 'sku']
$param = array_pop($path)
// $path = ['orderItems', 'product']
// $param = 'sku'
$dotPath = collect($path)->reduce(function ($c, $i) {
    return $c . $i . '.';
});
// $dotPath = 'orderItems.product.'

$dotPath = substr($dotPath, 0, -1)
// $dotPath = 'orderItems.product'

然后我们用whereHas

进行检查
$query->whereHas($dotPath, function ($query) use ($request, $param){
    $query->where($param, 'LIKE', '%' . $request->search . '%');
})->get();