Laravel 5.0 Eloquent三级关联咨询:表结构及模型关联代码
Laravel 5.0 Eloquent 三级关联实操指南
嘿,针对你提到的Laravel 5.0里Eloquent三级关联的问题,结合你给出的表结构和模型关联,我先把没写完的Currency模型关联补全(应该是一对多关联PropertyPrice),然后整理几个实用的操作场景和代码示例:
首先补全Currency模型的关联方法:
public function PropertyPrice() { return $this->hasMany('App\PropertyPrice', 'currency_id'); }
1. 从属性出发,加载关联的价格及对应货币
如果你想查询某个(或所有)Property时,同时拉取它的所有价格记录,以及每条价格对应的货币信息,用嵌套预加载就可以搞定,这是三级关联最常用的操作:
// 查询单个属性并加载所有关联的价格和货币 $property = Property::with('PropertyPrice.Currency')->find($propertyId); // 遍历输出示例 echo $property->title . "\n"; foreach ($property->PropertyPrice as $priceEntry) { echo "价格:{$priceEntry->price} {$priceEntry->Currency->title}\n"; } // 查询所有属性并批量加载关联数据(避免N+1查询问题) $allProperties = Property::with('PropertyPrice.Currency')->get();
这里的核心就是用点号.连接嵌套的关联关系PropertyPrice.Currency,告诉Eloquent要预加载到第三层的关联数据。
2. 从货币出发,加载关联的价格及对应属性
反过来,如果你想查某个货币下的所有价格记录,以及每条价格对应的属性信息,同样用嵌套预加载:
// 查询单个货币并加载关联的价格和属性 $currency = Currency::with('PropertyPrice.Property')->find($currencyId); // 遍历输出示例 echo $currency->title . "\n"; foreach ($currency->PropertyPrice as $priceEntry) { echo "价格:{$priceEntry->price},对应属性:{$priceEntry->Property->title}\n"; }
3. 带条件筛选的三级关联查询
如果需要筛选特定条件的关联数据,比如只加载关联了美元(假设currency_id=1)的属性及其价格,用whereHas结合嵌套关联就行:
// 写法一:多层嵌套whereHas $targetProperties = Property::with('PropertyPrice.Currency') ->whereHas('PropertyPrice', function ($query) { $query->whereHas('Currency', function ($subQuery) { $subQuery->where('currency_id', 1); }); }) ->get(); // 写法二:Laravel 5.0支持点号嵌套的whereHas,更简洁 $targetProperties = Property::with('PropertyPrice.Currency') ->whereHas('PropertyPrice.Currency', function ($query) { $query->where('currency_id', 1); }) ->get();
4. 自定义三级关联的查询逻辑
如果需要对关联数据做定制化筛选(比如只加载每个属性的最新价格),可以在模型里定义带约束的关联:
比如在Property模型里新增一个关联方法:
public function LatestPropertyPrice() { // 只关联最新的一条价格记录,同时预加载对应的货币 return $this->hasOne('App\PropertyPrice', 'property_id')->latest()->with('Currency'); }
使用的时候就可以直接拉取最新价格:
$property = Property::with('LatestPropertyPrice')->find($propertyId); echo "{$property->title}的最新价格:{$property->LatestPropertyPrice->price} {$property->LatestPropertyPrice->Currency->title}";
小提醒
- Laravel 5.0的Eloquent关联名称是区分大小写的,一定要确保你调用的关联名称和模型里定义的完全一致(比如模型里是
PropertyPrice,就别写成propertyPrice)。 - 预加载(
with方法)能有效避免N+1查询性能问题,处理关联数据时优先用它哦。
内容的提问来源于stack exchange,提问作者fuad
相关产品推荐
相关产品推荐

