
本文教你如何在 Laravel Blade 模板中正确展示外键关联的语义化数据(如 city_id 对应的 city_name),避免原始 SQL 查询,推荐使用 Eloquent 预加载关系 + 点语法访问,兼顾性能与可读性。
本文教你如何在 laravel blade 模板中正确展示外键关联的语义化数据(如 `city_id` 对应的 `city_name`),避免原始 sql 查询,推荐使用 eloquent 预加载关系 + 点语法访问,兼顾性能与可读性。
在 Laravel 开发中,直接使用 DB::select() 查询原始表数据虽可行,但会丢失模型关系能力,导致无法自然访问外键关联的语义化字段(例如 city_id 对应的城市名称)。你当前的 Villa 模型已正确定义了 City、Seller 和 Payment 关系,但控制器仍绕过 Eloquent 使用原生查询——这使关系方法完全失效。
✅ 正确做法是:改用 Eloquent 查询,并通过 with() 预加载关联数据,避免 N+1 查询问题。首先修正控制器逻辑:
// App\Http\Controllers\WebsiteController.php
public function index()
{
// ✅ 使用 Eloquent + with() 预加载关联模型(推荐)
$villas = Villa::with(['City', 'Seller', 'Payment'])->get();
return view('website', ['villas' => $villas]);
}⚠️ 注意:你的模型关系定义存在关键错误。当前写法:
public function City()
{
return $this->hasOne(City::class, 'id', 'city_id');
}这是 反向的 hasOne(即“城市拥有一个别墅”),而实际业务中是“别墅属于一个城市”,应使用 belongsTo:
// App\Models\Villa.php —— 修正后的关系定义
public function city() // 推荐小驼峰命名,符合 Laravel 约定
{
return $this->belongsTo(City::class, 'city_id', 'id');
}
public function seller()
{
return $this->belongsTo(Seller::class, 'seller_id', 'id');
}
public function payment()
{
return $this->belongsTo(Payment::class, 'payment_id', 'id');
}同时确保关联模型(如 City)中无需额外定义反向关系(除非你需要从城市查所有别墅),且 City 模型需包含 name 字段(假设为 name;若为 city_name 等,请按实际字段名调整)。
在 Blade 模板中,即可安全访问关联属性(Laravel 会自动处理空值):
<!-- website.blade.php -->
@foreach ($villas as $villa)
<div class="villa-block">
<a href="single-villa.html" id="villaname">{{ old('name', $villa->title) }}</a>
<!-- ✅ 安全访问关联城市名称:$villa->city->name -->
<a href="#" id="villaLocation">{{ $villa->city?->name ?? '未知城市' }}</a>
<!-- ✅ 同理访问卖家姓名与支付方式 -->
<span>卖家:{{ $villa->seller?->name ?? '未指定' }}</span>
<span>付款方式:{{ $villa->payment?->method ?? '未设置' }}</span>
</div>
@endforeach? 小贴士:
- 使用
?->空合并操作符(PHP 8.0+)可避免因关联记录缺失导致的Trying to get property on null错误; - 若需兼容旧版 PHP,改用
optional($villa->city)->name; -
with(['city', 'seller'])会一次性预加载所有关联,比循环中逐个调用$villa->city->name高效得多; -
protected $fillable中无需包含id、created_at等系统字段,Laravel 默认允许批量赋值的字段应仅为业务字段(如title,price,city_id等)。
总结:抛弃 DB::select(),拥抱 Eloquent 的关系能力;修正 belongsTo 关系定义;用 with() 预加载 + 点语法访问,让 Blade 模板简洁、健壮、可维护。


















