我想用Eloquent创建产品过滤器.
我是这样开始的
$query = Product::whereHas('variants')
->with('variants')
->with('reviews')
$query = $this->addOrderConstraints($request, $query);
$products = $query->paginate(20);
Run Code Online (Sandbox Code Playgroud)
哪里
private function addOrderConstraints($request, $query)
{
$order = $request->input('sort');
if ($order === 'new') {
$query->orderBy('products.created_at', 'DESC');
}
if ($order === 'price') {
$query->orderBy('variants.price', 'ASC');
}
return $query;
}
Run Code Online (Sandbox Code Playgroud)
但是,这不起作用,因为Eloquent正在执行此查询(来自Laravel DebugBar的信息)
select count(*) as aggregate from `products` where exists
(select * from `variants` where `products`.`id` = `variants`.`product_id`)
select * from `products` where exists
(select * from `variants` where `products`.`id` = `variants`.`product_id`)
select * from `variants` where `variants`.`product_id` in ('29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48')
Run Code Online (Sandbox Code Playgroud)
等等
因此,当我尝试按价格使用排序时,它只是明显的错误
Unknown column 'variants.price' in 'order clause' (SQL: select * from
`products` where exists (select * from `variants` where `products`.`id` =
Run Code Online (Sandbox Code Playgroud)
variants.product_id订购variants.priceasc limit 20 offset 0)
那么是否可以与Eloquent进行关系排序?
这将对子查询进行排序.不是"第一个查询(产品查询)".
基本上,你的子查询将是:
select * from variants where product_id in (....) order by price,这不是你想要的,对吧?
<?php
// ...
$order = $request->sort;
$products = Product::whereHas('variants')->with(['reviews', 'variants' => function($query) use ($order) {
if ($order == 'price') {
$query->orderBy('price');
}
}])->paginate(20);
Run Code Online (Sandbox Code Playgroud)
如果要对产品+ /或变体进行排序,则需要使用join.
$query = Product::select([
'products.*',
'variants.price',
'variants.product_id'
])->join('variants', 'products.id', '=', 'variants.product_id');
if ($order === 'new') {
$query->orderBy('products.created_at', 'DESC');
}
if ($order === 'price') {
$query->orderBy('variants.price');
}
return $query->paginate(20);
Run Code Online (Sandbox Code Playgroud)
如果您想对产品和变体进行排序,则不需要联接,因为您不会加载相关模型(如$product->variants),而仅加载变体表的所有字段。
要按相关子模型对模型进行排序,我们可以使用Eloquent - Subquery Ordering。
要通过相关模型而不是相关模型本身来对整个模型进行排序,我们可以这样做:
return Product::with('variants')->orderBy(
Variants::select('price')
// This can vary depending on the relationship
->whereColumn('variant_id', 'variants.id')
->orderBy('price')
->limit(1)
)->get();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7971 次 |
| 最近记录: |