laravel соединение и где условие на двух таблицах с нумерацией страниц - PullRequest
0 голосов
/ 21 февраля 2020


У меня есть:

Продукты

+--------------+--------------+
| id  | name   | description  |
+--------------+--------------+
| 1   | shirt  |  some desc   |
| 2   | shirt_b|  some desc   |
| 3   | shoe   |  some desc   |
| 4   | shirt_c|  some desc   |
+--------------+--------------+

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  |
--------------+--------+---------+


пользователь хочет выполнить поиск по названию продукта и диапазон цен , например:
ключевое слово: "рубашка", минимальная цена: "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>


как запросить в контроллере и показать их в виде с нумерацией страниц?

Ответы [ 2 ]

1 голос
/ 22 февраля 2020

Как сказано в комментариях, whereHas просто фильтрует результаты по обратному вызову. Но остальная часть комментария была неправильной. Чтобы включить значения из другой таблицы, используйте with , а также whereHas, а не вместо него.

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

Предполагая, что ваши модели 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)

Не идеально, что он запускает два запроса, но это Laravel.

В ваш макет, нет необходимости использовать метод отношения. Просто используйте свойство вместо:

@forelse($product->metas as $meta)
0 голосов
/ 21 февраля 2020

Определение моделей и соотношений. В продуктах модели:

        public function metas(){       
            return $this->hasMany('ProductMetas');
        }

Затем

$products = Products::with('metas')->where('name',$name)->where('price','=>', $LB)->where('price','<=',$UB)->simplePaginate(15);
return View::make('view.name', compact('products'));

Не забудьте получить имя и цену в зависимости от ввода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...