Laravel 9中使用Eloquent ORM无法获取关联表字段问题
问题分析与修复方案
报错Attempt to read property "deskripsi" on null的核心原因是$item->business返回了null,说明Eloquent关联未正确加载或数据本身无关联。以下是具体修复步骤:
1. 修正模型主键属性拼写错误
Laravel模型的主键属性为驼峰命名的$primaryKey,而非下划线命名的$primary_key,错误的属性名会导致Eloquent无法识别主键,进而影响关联逻辑:
Business模型修正:
class Business extends Model { use HasFactory; protected $table = 't_bisnis'; protected $guarded = []; // 修正属性名:$primary_key → $primaryKey protected $primaryKey = 'id'; protected $with = ['group']; protected $fillable = ['deskripsi', 'pemilik']; public function group(){ return $this->hasOne(GroupService::class, 'bisnis_id'); } }
GroupService模型修正:
class GroupService extends Model { use HasFactory; protected $table = 't_grup_layanan'; protected $guarded = []; // 修正属性名并设置正确主键值 protected $primaryKey = 'id'; protected $fillable = ['bisnis_id', 'deskripsi']; protected $with = []; public function service(){ return $this->hasMany(Service::class); } public function business() { return $this->belongsTo(Business::class, 'bisnis_id'); } }
2. 指定关联外键参数
由于你的外键字段是bisnis_id(而非Eloquent默认的business_id),需要在关联方法中显式指定外键,否则Eloquent会自动使用错误的外键名称查询,导致关联数据无法加载:
- 在
Business的group方法中添加外键参数'bisnis_id' - 在
GroupService的business方法中添加外键参数'bisnis_id'
3. 预加载关联避免N+1问题
控制器中使用all()不会预加载关联数据,循环中访问$item->business会触发额外查询,且可能因延迟加载逻辑导致关联为null。改用with()预加载关联:
class GroupServiceController extends Controller { public function index() { // 预加载business关联,确保数据一次性加载完成 $list = GroupService::with('business')->get(); return view('dashboard.gruplayanan.main', compact('list')); } }
4. 处理视图中关联为null的场景
因为bisnis_id设置为nullable(),部分GroupService记录可能未关联Business,直接访问$item->business->deskripsi会报错。可以使用可选链操作符(PHP 8.0+)或条件判断兼容低版本PHP:
方案1(PHP 8.0+推荐):
<td>{{ $item->business?->deskripsi ?? '-' }}</td>
方案2(兼容低版本PHP):
<td>@if($item->business){{ $item->business->deskripsi }}@else-@endif</td>
内容的提问来源于stack exchange,提问作者ProgrammerWannabe
相关产品推荐
相关产品推荐

