Laravel 5.1:带WHERE条件的多态关联查询问题
解决多态关联中筛选关联对象字段的问题
嘿,我看你在处理多态关联的查询时遇到了麻烦,就是要根据关联对象的字段来筛选结果对吧?结合你给的示例数据,我来给你梳理几种常见场景的解决办法,都是Laravel里常用的操作:
场景1:查询关联特定类型对象且满足字段条件的Content
比如你想找所有关联MusicTrack且page_id = 1的Content记录(就是你示例里那条content_id=555的),直接用Laravel专门为多态关联做的whereHasMorph方法就行,代码是这样的:
use App\Content; use App\MusicTrack; $contents = Content::whereHasMorph('contentable', [MusicTrack::class], function ($query) { $query->where('page_id', 1); })->get();
如果需要同时筛选多种类型的对象,比如同时找关联MusicTrack和Image且page_id=1的Content,只需要把类型数组扩大:
use App\Image; $contents = Content::whereHasMorph('contentable', [MusicTrack::class, Image::class], function ($query) { $query->where('page_id', 1); })->get();
场景2:查询拥有符合条件的多态关联对象的Page
如果你想反过来,找所有拥有关联MusicTrack(且MusicTrack满足某个条件)的Page,那可以通过嵌套的whereHas来实现,前提是你的Page模型已经定义了和MusicTrack的关联:
首先在Page模型里加关联:
class Page extends Model { public function musicTracks() { return $this->hasMany(MusicTrack::class); } public function videos() { return $this->hasMany(Video::class); } public function images() { return $this->hasMany(Image::class); } }
然后就可以这样查询:
$pages = Page::whereHas('musicTracks.content', function ($query) { // 这里可以筛选关联的MusicTrack字段,比如找id=10的MusicTrack对应的Page $query->whereHasMorph('contentable', MusicTrack::class, function ($q) { $q->where('id', 10); }); })->get();
场景3:跨所有多态类型筛选通用字段
如果你的MusicTrack、Video、Image都有同一个字段(比如page_id),你想筛选所有关联对象的该字段等于某个值的Content,可以直接用*匹配所有多态类型:
$contents = Content::whereHasMorph('contentable', '*', function ($query) { $query->where('page_id', 1); })->get();
这样不管关联的是音乐、视频还是图片,只要对应模型的page_id是1,都会被筛选出来。
旧版本Laravel的兼容方案
如果你的Laravel版本低于5.8,whereHasMorph还没出,那可以用原生SQL的方式来实现,比如筛选关联MusicTrack且page_id=1的Content:
use Illuminate\Support\Facades\DB; $contents = Content::where(function ($query) { $query->where('contentable_type', MusicTrack::class) ->whereExists(function ($q) { $q->select(DB::raw(1)) ->from('music_tracks') ->whereColumn('music_tracks.id', 'contents.contentable_id') ->where('music_tracks.page_id', 1); }); })->get();
这样应该就能解决你在多态关联查询中筛选关联对象字段的问题了。
内容的提问来源于stack exchange,提问作者Leon
相关产品推荐
相关产品推荐

