Laravel访问sitemaps.xml报错:Attempt to read property "slug" on null
Laravel Sitemap报错‘Attempt to read property "slug" on null’分析与解决
错误原因
报错出现在{{ url('category', [$subcategory->category->slug, $subcategory->slug]) }}这行代码,核心问题是某个子分类($subcategory)的关联父分类($subcategory->category)为null,导致尝试读取slug属性时触发错误。具体触发场景包括:
- 数据库中存在
subcategory记录,但其category_id字段为null,或该字段指向的category记录已被删除 - 子分类模型(Subcategory)与父分类模型(Category)的关联定义错误,无法正确加载关联数据
- 生成sitemap时的查询未过滤掉无有效父分类的子分类
解决办法
1. 修复无效数据
先定位数据库中的无效子分类记录:
SELECT * FROM subcategories WHERE category_id IS NULL OR NOT EXISTS (SELECT 1 FROM categories WHERE id = subcategories.category_id);
根据业务需求处理这些记录:
- 给无效记录补充正确的
category_id - 删除无有效父分类的子分类
2. 视图层添加防御判断
在视图中先判断父分类是否存在,再生成URL:
@if($subcategory->category) {{ url('category', [$subcategory->category->slug, $subcategory->slug]) }} @endif
如果使用Laravel 8及以上版本,也可以用可选链简化判断(需注意空值场景的URL生成逻辑):
{{ $subcategory->category ? url('category', [$subcategory->category->slug, $subcategory->slug]) : '' }}
3. 查询时过滤有效子分类
在获取子分类数据的逻辑中,只加载存在有效父分类的记录,同时预加载关联避免N+1问题:
// 控制器/逻辑层代码 $subcategories = Subcategory::with('category')->has('category')->get();
has('category')会自动过滤掉没有关联父分类的子分类。
4. 模型与迁移优化
- 确保Subcategory模型的关联定义正确:
// app/Models/Subcategory.php public function category() { return $this->belongsTo(Category::class); } - 给
subcategories表的category_id添加外键约束,从根源避免无效关联:// 迁移文件 public function up() { Schema::table('subcategories', function (Blueprint $table) { $table->foreignId('category_id')->constrained()->onDelete('cascade'); }); }onDelete('cascade')表示删除父分类时自动删除关联子分类,若业务允许也可设置为onDelete('set null'),但需确保category_id字段允许为null。
内容的提问来源于stack exchange,提问作者Priyantha Jey
相关产品推荐
相关产品推荐

