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>
错误原因排查
- 模型关联定义错误:Product与ProductCategory的关联可能未正确指定主键/外键,Laravel默认用
id字段关联,但你的分类表主键是category_id,不指定会导致查询失败。 - 数据不一致:部分产品的
category_id指向的分类记录已被删除,查询时找不到对应的ProductCategory模型。 - 视图字段错误:视图中调用
$items->category->title,但分类表实际字段是category_name,无效属性调用可能引发连锁错误。 - 控制器逻辑问题:创建报价的控制器可能使用了
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
相关产品推荐
相关产品推荐

