You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel中实现商品按关联分类展示?

解决Laravel分类点击展示对应商品的问题

没问题,我帮你一步步搞定这个需求!咱们从最基础的模型关联开始,再到路由、控制器,最后调整视图和商品展示,整个流程很清晰:

1. 补全模型间的关联关系

首先你的模型里还没建立分类和商品的关联,这是实现需求的关键:

Product模型

先把模型类名改成Product(首字母大写符合Laravel规范),然后添加和分类的关联:

namespace App;
use Illuminate\Database\Eloquent\Model;

class Product extends Model {
    protected $fillable = [
        'id', 'product_name', 'product_price', 'product_image', 'product_brand', 'category_id'
    ];

    // 一个商品属于一个分类
    public function category()
    {
        return $this->belongsTo(Category::class);
    }
}

小提示:数据库里的Category_id字段建议改成category_id(全小写下划线命名),符合Laravel的默认命名约定,避免后续踩坑。

Category模型

同样把类名改成Category,然后添加和商品的关联:

namespace App;
use Illuminate\Database\Eloquent\Model;

class Category extends Model {
    protected $table = "category";
    protected $fillable = ['cate_name', 'p_id'];

    // 你已经写好的子分类关联
    public function childs() {
        return $this->hasMany(Category::class,'p_id');
    }

    // 一个分类对应多个商品
    public function products()
    {
        return $this->hasMany(Product::class, 'category_id');
    }
}

2. 配置路由

在routes/web.php里加一条专门用来展示分类商品的路由:

// 展示指定分类下的商品,路由命名方便视图调用
Route::get('/category/{category}', [CategoryController::class, 'showProducts'])->name('category.products');

3. 编写控制器逻辑

先生成CategoryController(如果还没有的话):

php artisan make:controller CategoryController

然后在app/Http/Controllers/CategoryController.php里添加处理方法:

namespace App\Http\Controllers;

use App\Category;

class CategoryController extends Controller
{
    public function showProducts(Category $category)
    {
        // 预加载商品关联,避免N+1查询问题,提升性能
        $category->load('products');
        
        // 如果你希望点击父分类时展示所有子分类的商品,可以用下面这段替换上面的load
        // $categoryIds = $category->descendants()->pluck('id')->push($category->id);
        // $products = \App\Product::whereIn('category_id', $categoryIds)->get();
        
        return view('category.products', compact('category'));
    }
}

4. 修改视图的跳转链接

现在把你菜单里的分类链接都改成我们刚才定义的路由,传递分类实例就行:

一级分类链接

<a id="cate" class="nav-links__item-link" href="{{ route('category.products', $firstmenu) }}">
    <div class="nav-links__item-body">
        {{$firstmenu->cate_name}}
        <svg class="nav-links__item-arrow" width="9px" height="6px">
            <use xlink:href="public/assets/images/sprite.svg#arrow-rounded-down-9x6"></use>
        </svg>
    </div>
</a>

二级分类链接

<a href="{{ route('category.products', $secondmenu) }}">{{$secondmenu->cate_name}}</a>

三级分类链接

<li class="megamenu__item"><a href="{{ route('category.products', $thirdmenu) }}">{{$thirdmenu->cate_name}}</a></li>

5. 创建商品展示页面

新建resources/views/category/products.blade.php,用来展示对应分类下的商品:

<div class="container">
    <h2>{{ $category->cate_name }} 商品列表</h2>
    
    @if($category->products->isEmpty())
        <p class="text-muted">这个分类还没有商品哦~</p>
    @else
        <div class="row">
            @foreach($category->products as $product)
                <div class="col-md-4 mb-4">
                    <div class="card h-100">
                        @if($product->product_image)
                            <img src="{{ asset('storage/' . $product->product_image) }}" class="card-img-top" alt="{{ $product->product_name }}">
                        @endif
                        <div class="card-body">
                            <h5 class="card-title">{{ $product->product_name }}</h5>
                            <p class="card-text">¥{{ $product->product_price }}</p>
                            <p class="card-text small">品牌:{{ $product->product_brand }}</p>
                        </div>
                    </div>
                </div>
            @endforeach
        </div>
    @endif
</div>

注意:如果你的商品图片存在storage/app/public目录下,记得先执行php artisan storage:link命令,创建public到storage的软链接,这样图片才能正常访问。

这样一套流程下来,点击菜单里的任意分类,就能跳转到对应的商品列表页面啦!如果需要调整样式或者扩展功能,比如分页、筛选,都可以在这个基础上继续完善~


内容的提问来源于stack exchange,提问作者user12310958

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:01:53