Laravel中如何从多对多关联中间表筛选符合条件的商家
问题描述
Sellers表为主表,Services表和Areas表用于存储特定商家的多项服务及服务区域。通过seller_services和sellerable中间表,使用belongsToMany()关联来获取服务和区域数据。
模型关联代码
// Seller模型 public function services() { return $this->belongsToMany('App\Models\Service'); } public function areas() { return $this->morphedByMany('App\Models\Area', 'sellerable'); } // Service模型 public function sellers() { return $this->belongsToMany('App\Models\Seller'); } // Area模型 public function sellers() { return $this->morphToMany('App\Models\Seller', 'sellerable'); }
当前问题
当请求指定服务和指定区域时,需要获取同时拥有该服务和该区域的所有商家,但现有方法无法实现这一双重条件匹配。
尝试过的查询代码
$service_name = Service::where('slug', $request->service)->first(); $area = Area::findOrFail($request->area); $sellers = $service_name->sellers; $sellers = $area->sellers;
尝试过的Blade模板代码
@if ($sellers) @foreach ($sellers as $seller) {{$seller->name}} @endforeach @endif
另一种尝试的模板代码
@if ($service_name) @foreach ($service_name->sellers and $area_name->sellers as $seller) {{$seller->name}} @endforeach @endif
以上方法均无法获取同时满足服务和区域条件的商家,需要实现能匹配这两个条件的商家查询。
解决方案
可以通过whereHas方法同时过滤关联的服务和区域条件,直接查询符合要求的商家:
$serviceSlug = $request->service; $areaId = $request->area; $sellers = Seller::whereHas('services', function ($query) use ($serviceSlug) { $query->where('slug', $serviceSlug); })->whereHas('areas', function ($query) use ($areaId) { $query->where('id', $areaId); })->get();
之后在Blade模板中直接循环结果即可:
@if ($sellers->isNotEmpty()) @foreach ($sellers as $seller) {{ $seller->name }} @endforeach @endif
补充说明
whereHas用于筛选存在指定关联条件的模型实例,两个whereHas叠加即可实现“同时满足两个关联条件”的逻辑- 也可以先获取服务和区域实例,再用实例ID进行筛选,效果一致:
$service = Service::where('slug', $serviceSlug)->firstOrFail(); $area = Area::findOrFail($areaId); $sellers = Seller::whereHas('services', fn($q) => $q->where('id', $service->id)) ->whereHas('areas', fn($q) => $q->where('id', $area->id)) ->get();
内容的提问来源于stack exchange,提问作者Moenul Islam
相关产品推荐
相关产品推荐

