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

Laravel 9创建报价项时出现ProductCategory模型查询无结果错误求助

解决Laravel 9中创建报价时出现的ProductCategory模型查询无结果错误

问题说明

在Laravel 9项目里,每次创建新报价项都会触发No query results for model [App\Models\ProductCategory]错误。项目包含两个核心视图:录入产品信息的product视图(从ProductCategory拉取分类数据生成下拉框),以及创建新报价的create quotation视图。

数据库表结构:

  • products表:含category_id字段,关联产品分类
  • product_categories表:含category_id(主键)和category_name字段

相关代码如下:

ProductCategoryController代码

class ProductCategoryController extends AccountBaseController
{
    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $this->categories = ProductCategory::all();
        return view('products.category.create', $this->data);
    }
    /**
     * @param StoreProductCategory $request
     * @return array
     * @throws \Ec\RestAPI\Exceptions\RelatedResourceNotFoundException
     */
    public function store(StoreProductCategory $request)
    {
        $category = new ProductCategory();
        $category->category_name = $request->category_name;
        $category->save();

        $categories = ProductCategory::get();
        $options = BaseModel::options($categories, $category, 'category_name');
        return Reply::successWithData(__('messages.categoryAdded'), ['data' => $options]);
    }
}

ProductController代码(部分)

class ProductController extends AccountBaseController { 
    public function __construct() {
    parent::__construct();
    $this->pageTitle = 'app.menu.products';
    $this->middleware(function ($request, $next) {
    in_array('client', user_roles()) ? abort_403(!(in_array('orders', $this->user->modules) && user()->permission('add_order') == 'all')) : abort_403(!in_array('products', $this->user->modules));

                return $next($request);
            });
        }
        
        /**
         * @param ProductsDataTable $dataTable
         * @return mixed|void
         */
        public function index(ProductsDataTable $dataTable) {
            $viewPermission = user()->permission('view_product');
            abort_403(!in_array($viewPermission, ['all', 'added']));
            $productDetails = [];
            if (request()->hasCookie('productDetails')) {
                $productDetails = json_decode(request()->cookie('productDetails'), true);
            }
            $this->productDetails = $productDetails;
            $this->totalProducts = Product::count();
            $this->categories = ProductCategory::all();
            $this->subCategories = ProductSubCategory::all();
        
            return $dataTable->render('products.index', $this->data);
        }
}

报价视图相关代码片段

<td class="border-bottom-0"><input type="hidden" id="category" name="category[]" value="{{ $items->category->category_id }}">{{ $items->category->title }}</td>

错误原因排查

  1. 模型关联定义错误:Product与ProductCategory的关联可能未正确指定主键/外键,Laravel默认用id字段关联,但你的分类表主键是category_id,不指定会导致查询失败。
  2. 数据不一致:部分产品的category_id指向的分类记录已被删除,查询时找不到对应的ProductCategory模型。
  3. 视图字段错误:视图中调用$items->category->title,但分类表实际字段是category_name,无效属性调用可能引发连锁错误。
  4. 控制器逻辑问题:创建报价的控制器可能使用了findOrFail()查询分类ID,当ID无效时直接抛出错误。

具体解决步骤

1. 修正Product模型的关联定义

打开App/Models/Product.php,确保关联正确指定字段:

public function category()
{
    // 明确指定外键和关联的主键
    return $this->belongsTo(ProductCategory::class, 'category_id', 'category_id');
}

2. 修复视图中的空关联与字段错误

修改报价视图代码,用optional()处理关联为空的情况,同时替换不存在的title字段为category_name:

<td class="border-bottom-0">
    <input type="hidden" id="category" name="category[]" value="{{ optional($items->category)->category_id ?? '' }}">
    {{ optional($items->category)->category_name ?? '未分类' }}
</td>

3. 清理数据库中的无效数据

执行SQL查询找出关联失效的产品:

SELECT p.* FROM products p 
LEFT JOIN product_categories pc ON p.category_id = pc.category_id 
WHERE pc.category_id IS NULL;

对这类数据做如下处理:

  • 为产品分配有效的分类ID
  • 删除无效产品
  • 若允许无分类,将产品的category_id设为NULL(需先修改表结构允许该字段为空)

4. 调整报价控制器的查询逻辑

如果报价创建控制器中使用了findOrFail(),改为find()并处理空值:

// 错误写法
$category = ProductCategory::findOrFail($request->category_id);

// 修正写法
$category = ProductCategory::find($request->category_id);
if (!$category) {
    return Reply::error('指定的分类不存在,请检查后重试');
}

5. 可选:设置关联默认值

如果允许产品无分类,可以在Product模型中设置关联默认值,避免视图报错:

public function category()
{
    return $this->belongsTo(ProductCategory::class, 'category_id', 'category_id')->withDefault([
        'category_name' => '未分类',
        'category_id' => 0
    ]);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 21:37:52