如何使用Laravel中的多对多关系检索嵌套类别的产品并排序结果?

问题描述 投票:0回答:1

我想检索所选类别以及子类别的产品,甚至可能需要根据价格或日期订购它们。请让我知道应该对控制器进行哪些更改!

我在两个表中使用多对多关系:类别和产品,以及将两者关联的category_product。

示例

(并非所有类别都有子类别)

礼物

书籍

玩具

  • 男孩

  • 女孩

电话

  • 三星

  • 诺基亚

如果用户单击“电话”,则应显示“电话”,“三星”或“诺基亚”类别的所有产品!

数据库

Products: id, name, price, created_at
Categories: id, name, slug, parent_id, sorting_order, created_at
category_product: id, category_id, product_id

代码:

类别模型:

class Category extends Model
{
    public function products()
    {
        return $this->belongsToMany('App\Product');
    }

    public function parent()
    {
        return $this->belongsTo('App\Category', 'parent_id');
    }

    public function children()
    {
        return $this->hasMany('App\Category', 'parent_id');
    }
}

产品型号

class Product extends Model
{
    public function categories()
    {
        return $this->belongsToMany('App\Category');
    }
}
class ProductController extends Controller {

    public function index($slug, Request $request)
    {
        if ( ! isset($_GET['sortBy']))
        {
            $category = Category::where('slug', $slug)->with('products')->first();

            if ( ! $category)
            {
                abort(404, 'Page not found');
            }
        }
        else
        {
            $slug = $request->segments()[1];
            $products = Category::where('slug', $slug);
            switch ($request->sortBy)
            {
                case 'latest':
                    $category = $products->with(['products' => function ($q) {
                        $q->orderBy('created_at', 'desc');
                    }])->first();
                    break;
                case 'asc':
                    $category = $products->with(['products' => function ($q) {
                        $q->orderBy('price', 'asc');
                    }])->first();
                    break;
                case 'desc':
                    $category = $products->with(['products' => function ($q) {
                        $q->orderBy('price', 'desc');
                    }])->first();
                    break;
                default:
                    $category = $products->with('products')->first();
                    break;
            }
        }

        return view('products', compact('category'));
    }
}

查看

<form id="sortProducts" class="form-inline" method="get">
   {{ csrf_field() }}
   <label for="sortBy">Sort By:</label>
   <select name="sortBy" id="sortBy">
      <option value="latest">Latest</option>
      <option value="asc">Price Low to Hight</option>
      <option value="desc">Price High to Low</option>
   </select>
</form>

@foreach($category->products as $product)
    <div class="product">
        <img border="0" src="{{Voyager::image($product->image)}}" alt="{{$product->name}}">
        <div class="product-name">{{$product->name}}</div>
        <div class="product-price">${{$product->price}}</div>
    </div>
@endforeach

我正在使用Laravel 6.2版和Voyager 1.3版。

php laravel categories voyager
1个回答
0
投票

如果您的类别深度不受限制,则需要递归关系。

我认为类似的方法可能有效:

在您的类别模型中:

public function nestedStructure()
{
   return $this->children()->with([
         'nestedStructure',
         'products' => function($q) {
             $q->orderBy('created_at', 'desc');
         }
   );
}
© www.soinside.com 2019 - 2024. All rights reserved.