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

Laravel如何通过公共列关联两表并按分类筛选展示商品?

问题描述

我有一个带6个分类按钮的页面,点击任意分类按钮后会跳转至对应页面,期望在目标页面根据分类筛选展示对应商品,但目前出现异常:要么没有数据展示,要么显示表中全部商品。比如点击Rims分类按钮后,希望在../shop/{category}页面只展示轮毂类商品。


相关代码与表结构

web.php

// shop
Route::get('/shop', function () {
    return view('shop');
})->middleware(['auth', 'verified'])->name('shop');

// categories display
Route::get('/shop', [CategoriesController::class, 'index'])->name('shop.index');


// accessing categories
Route::get('/shop/{name}', [ProductsController::class, 'index'])->name('show-products');

ProductsController.php

<?php

namespace App\Http\Controllers;

use App\Http\Requests\ProfileUpdateRequest;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redirect;
use Illuminate\View\View;
use App\Models\Categories;
use App\Models\Products;
use Illuminate\Support\Facades\DB;

class ProductsController extends Controller
{
    public function store(Request $product)
    {
        $product->validate([
            'name' => ['required', 'string', 'max:500'],
            'brand' => ['required', 'string', 'max:500'],
            'category' => ['required', 'string', 'max:500'],
            'description' => ['required', 'string', 'max:500'],
            'quantity' => ['required', 'string', 'max:500'],
            'price' => ['required', 'string', 'max:500'],
            'image' => ['required', 'string', 'max:500']
        ]);

        $product = Products::create([
            'name' => $product->name,
            'brand' => $product->brand,
            'category' => $product->category,
            'description' => $product->description,
            'quantity' => $product->quantity,
            'price' => $product->price,
            'image' => $product->image,
        ]);

        return redirect('/shop');
    }

    /**
     * Listeaza categoriile
     */
    public function index(Request $product, $category)
    {
            $products = Products::all();
            $categories = Categories::all();

            $category = DB::table('categories')
                ->join('products', 'categories.category', '=', 'products.category')
                ->select('categories.category')
                ->get();
            return view('products', ['category'=>$category, 'products'=>$products]);
    }
}

表结构截图

  • categories表:categories表结构
  • products表:products表结构

已尝试的方法

我试过在ProductController和CategoryController之间用if语句(比如$product->category == $category->category)匹配分类,也尝试关联两张表的分类字段,但问题还是没解决。


解决方案

1. 修复路由冲突与参数不匹配问题

当前/shop路由存在重复定义,会导致逻辑覆盖;同时路由参数{name}与控制器接收的$category参数名不对应,修改web.php:

// 保留一个处理分类展示的shop路由,移除重复定义
Route::get('/shop', [CategoriesController::class, 'index'])->middleware(['auth', 'verified'])->name('shop.index');

// 统一参数名为category,与控制器方法接收参数对应
Route::get('/shop/{category}', [ProductsController::class, 'index'])->name('show-products');

2. 修正ProductsController的筛选逻辑

当前方法直接查询所有商品,且覆盖了路由传入的分类参数,修改为按分类筛选:

public function index(Request $request, $categoryName)
{
    // 根据路由传入的分类名称筛选对应商品
    $products = Products::where('category', $categoryName)->get();
    // 获取所有分类用于页面导航(如果需要)
    $categories = Categories::all();
    
    // 将筛选结果传递给视图
    return view('products', compact('products', 'categories', 'categoryName'));
}

3. 确保分类按钮跳转链接正确

分类按钮的跳转链接要指向正确的路由,比如Rims分类的链接写法:

<a href="{{ route('show-products', ['category' => 'Rims']) }}">Rims</a>

4. 可选:优化模型关联(增强容错性)

如果想避免分类名称不存在的情况,可以在Categories模型定义关联:

// Categories.php
public function products()
{
    return $this->hasMany(Products::class, 'category', 'category');
}

然后控制器中可以通过关联查询,同时处理分类不存在的情况:

public function index(Request $request, $categoryName)
{
    // 若分类不存在则返回404
    $category = Categories::where('category', $categoryName)->firstOrFail();
    // 通过关联获取该分类下的所有商品
    $products = $category->products;
    $categories = Categories::all();
    
    return view('products', compact('products', 'categories', 'category'));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 02:30:07