[英]laravel join and where condition on two tables with pagination
Products产品
+--------------+--------------+
| id | name | description |
+--------------+--------------+
| 1 | shirt | some desc |
| 2 | shirt_b| some desc |
| 3 | shoe | some desc |
| 4 | shirt_c| some desc |
+--------------+--------------+
Product_metas Product_metas
--------------+---------+--------+
| product_id | color | price |
--------------+---------+--------+
| 1 | black | 2000 |
| 1 | red | 6000 |
| 1 | brown | 8000 |
| 2 | black | 6000 |
| 2 | green | 4000 |
| 3 | blue | 7000 |
| 4 | red | 9000 |
| 4 | blue | 2000 |
| 4 | black | 8000 |
--------------+--------+---------+
user wants to search with product name and price range like this :用户想用这样的产品名称和价格范围进行搜索:
keyword : "shirt" , min-price: "5000", max-price: "10000"关键字:“衬衫”,最低价格:“5000”,最高价格:“10000”
[
0 : [
Name : shirt
Desc : some desc
metas [
0 : [red , 6000],
1 : [brown , 8000],
]
],
1 : [
Name : shirt_b
Desc : some desc
metas [
0 : [black , 6000],
]
],
2 : [
Name : shirt_c
Desc : some desc
metas [
0 : [red , 9000],
1 : [black , 8000],
]
],
]
$products = Product::where('name', 'like', '%' . $request->input('keyword') . '%')
->whereHas('metas', function($query) use ($request) {
$query->whereBetween('price', [
$request->input('price_min'),
$request->input('price_max')
]);
})
->paginate(10);
return view('/home' , compact(['products']));
<div>
{!! $products->render() !!}
@forelse($products as $product)
<ul>
<li><strong>Name : </strong>{{ $product->name }}</li>
<li><strong>Desc : </strong>{{ $product->desc }}</li>
<ul>
@forelse($product->metas()->get() as $meta)
<li><strong>Color : </strong>{{ $meta->color }}<strong> --> $ </strong>{{ $meta->price }}</li>
@empty
<h3>no meta</h3>
@endforelse
</ul>
</ul>
@empty
<h3>no data</h3>
@endforelse
</div>
how i should query in controller and show them in view with pagination ?我应该如何在控制器中查询并使用分页显示它们?
As said in comments, whereHas
just filters results based on the callback.正如评论中所说,
whereHas
只是根据回调过滤结果。 But the rest of the comment was wrong.但其余的评论是错误的。 To include the values from the other table, use
with
as well as whereHas
, not instead of it.要包含另一个表中的值,请使用
with
和whereHas
,而不是代替 it。
$products = Product::where('name', 'like', '%' . $request->keyword . '%')
->whereHas('metas', function($query) use ($request) {
$query->whereBetween('price', [$request->price_min, $request->price_max]);
})
->with('metas')
->paginate(10);
return view('/home' , compact('products'));
Assuming your Product
and Meta
models have proper relationships, this will generate the following SQL queries, returning the results you want:假设您的
Product
和Meta
模型具有适当的关系,这将生成以下 SQL 查询,返回您想要的结果:
select * from `products` where `name` like '%shirt%' and exists (select * from `product_metas` where `products`.`id` = `product_metas`.`product_id` and `price` between 5000 and 1000);
select * from `product_metas` where `product_metas`.`product_id` in (1, 2, 4)
Not ideal that it runs two queries, but that's Laravel.它运行两个查询并不理想,但那是 Laravel。
In your layout, no need to use the relation method.在您的布局中,无需使用关系方法。 Just use the property instead:
只需使用该属性:
@forelse($product->metas as $meta)
Define models and raletions.定义模型和关系。 In Products model:
在产品型号中:
public function metas(){
return $this->hasMany('ProductMetas');
}
Then然后
$products = Products::with('metas')->where('name',$name)->where('price','=>', $LB)->where('price','<=',$UB)->simplePaginate(15);
return View::make('view.name', compact('products'));
Remember to get name, and price bounds from input.请记住从输入中获取名称和价格范围。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.