简体   繁体   English

laravel join 和 where 条件在两个带分页的表上

[英]laravel join and where condition on two tables with pagination


I have this:我有这个:

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”

and result of this search should be like this (with pagination):此搜索的结果应如下所示(带分页):

[
    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],
            ]
        ],
]

Controller:控制器:

$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']));

view:看法:

<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.要包含另一个表中的值,请使用withwhereHas ,而不是代替 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:假设您的ProductMeta模型具有适当的关系,这将生成以下 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM