Laravel 9 同表双外键关联报错:读取accountName属性失败
问题排查:Attempt to read property "accountName" on int
问题原因
Transfer模型中,关联方法名fromAccount、toAccount与数据表的字段名完全一致。Laravel在访问模型属性时,会优先检查是否存在对应的数据表字段,因此$transfer->fromAccount返回的是数据库中存储的整数ID,而非关联的Bank模型实例,后续尝试读取accountName自然会触发"在int上读取属性"的错误。
解决方案
方案1:修改关联方法名(推荐)
将关联方法名与字段名区分开,符合Laravel命名规范,避免冲突:
- 更新Transfer模型:
class Transfer extends Model { use HasFactory; protected $fillable = [ 'fromAccount', 'toAccount', 'amount', 'rate', 'date', 'reference', 'description', 'created_by', ]; // 修改关联方法名,与字段名区分 public function fromBank() { return $this->belongsTo(Bank::class, 'fromAccount'); } public function toBank() { return $this->belongsTo(Bank::class, 'toAccount'); } }
- 更新TransferController的index方法:
public function index() { // 预加载修改后的关联 $transfers = Transfer::with('fromBank', 'toBank')->get(); return view('backend.pages.transfers.index', compact('transfers')); }
- 更新视图blade文件:
@foreach ($transfers as $transfer) <tr> <td class="fw-semibold">{{ $transfer->date }}</td> <!-- 使用修改后的关联方法名访问模型属性,添加空值保护 --> <td>{{ optional($transfer->fromBank)->accountName ?? '已删除账户' }}</td> <td>{{ optional($transfer->toBank)->accountName ?? '已删除账户' }}</td> </tr> @endforeach
注:添加optional()和空值合并运算符是为了处理银行账户被删除的场景,避免空模型报错。
方案2:调用关联方法获取实例(不推荐)
如果不想修改方法名,可以主动调用关联方法(加括号)获取模型实例:
@foreach ($transfers as $transfer) <tr> <td class="fw-semibold">{{ $transfer->date }}</td> <td>{{ $transfer->fromAccount()->first()->accountName ?? '已删除账户' }}</td> <td>{{ $transfer->toAccount()->first()->accountName ?? '已删除账户' }}</td> </tr> @endforeach
注意:需保留控制器中的with('fromAccount', 'toAccount')预加载,否则会产生N+1查询问题。
内容的提问来源于stack exchange,提问作者user1404396
相关产品推荐
相关产品推荐

