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

一对多关联中父模型无子模型时触发非对象错误求助

问题分析与解决方案

错误原因

当服务器没有对应的server_status记录时,$server->serverStatus会返回一个空的Collection,调用->last()方法后得到的是null。此时你尝试访问null->status_id,就会触发“Trying to get property 'status_id' of non-object”的错误——因为null不是对象,根本无法读取它的属性。你之前写的elseif($server->serverStatus->last()->status_id === null)永远不会被执行,因为在执行到这行代码之前就已经报错中断了。

解决方案

我们可以通过两种方式避免这个错误:提前检查状态记录是否存在,或者使用Laravel提供的optional()辅助函数来安全访问属性。

方案1:先获取最新状态并检查是否存在

在模板里先把最新的状态记录存到变量里,再判断是否存在,之后再访问status_id:

@php
    $latestStatus = $server->serverStatus->last();
@endphp

@if($latestStatus && $latestStatus->status_id === 1)
    <a href="/servers/{{$server->id}}" class="text-dark list-group-item list-group-item-success">{{$server->name}}</a>
@elseif($latestStatus && $latestStatus->status_id === 2)
    <a href="/servers/{{$server->id}}" class="text-dark list-group-item list-group-item-warning">{{$server->name}}</a>
@elseif($latestStatus && $latestStatus->status_id === 3)
    <a href="/servers/{{$server->id}}" class="text-dark list-group-item list-group-item-danger">{{$server->name}}</a>
@elseif($latestStatus && $latestStatus->status_id === 4)
    <a href="/servers/{{$server->id}}" class="text-dark list-group-item list-group-item-warning">{{$server->name}} is under maintenance</a>
@else
    <a href="/servers/{{$server->id}}" class="text-dark list-group-item list-group-item-warning">{{$server->name}} has no inputted status</a>
@endif

方案2:使用optional()辅助函数

Laravel的optional()函数可以安全地访问对象属性,如果传入的是null,它会返回null而不是抛出错误:

@if(optional($server->serverStatus->last())->status_id === 1)
    <a href="/servers/{{$server->id}}" class="text-dark list-group-item list-group-item-success">{{$server->name}}</a>
@elseif(optional($server->serverStatus->last())->status_id === 2)
    <a href="/servers/{{$server->id}}" class="text-dark list-group-item list-group-item-warning">{{$server->name}}</a>
@elseif(optional($server->serverStatus->last())->status_id === 3)
    <a href="/servers/{{$server->id}}" class="text-dark list-group-item list-group-item-danger">{{$server->name}}</a>
@elseif(optional($server->serverStatus->last())->status_id === 4)
    <a href="/servers/{{$server->id}}" class="text-dark list-group-item list-group-item-warning">{{$server->name}} is under maintenance</a>
@else
    <a href="/servers/{{$server->id}}" class="text-dark list-group-item list-group-item-warning">{{$server->name}} has no inputted status</a>
@endif

额外优化:预加载关联避免N+1查询

另外,建议在控制器里预加载serverStatus关联,这样可以避免执行大量重复的查询,提升页面性能:

public function index(){
    // 使用with()预加载关联
    $servers = Server::with('serverStatus')->orderBy('created_at', 'desc')->get();
    $incidents = Incident::orderBy('created_at', 'desc')->paginate(10);
    return view('pages.index', ['incidents' => $incidents, 'servers' => $servers]);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:16:55