Eloquent with/whereHas 的疑问
最近开发的一个项目常常要求多表联合查询,就免不了使用Eloquent的with和whereHas.
with
http://www.golaravel.com/laravel/docs/5.0/...
预载入。其实这个不是本次讨论的核心。
$posts = Post::with(['comments' => function($query)
{
$query->where('content', 'like', 'foo%');
}])->get();
whereHas
http://www.golaravel.com/laravel/docs/5.0/...
关联查询。这个才是重点。
$posts = Post::whereHas('comments', function($q)
{
$q->where('content', 'like', 'foo%');
})->get();
从上面两段代码可看出,with和whereHas的函数用法是很类似的。具体区别前者是为了减少数据库请求次数,后者是作为条件来过滤Post。
这里就有个有趣的事情。
-
设想Post和Comment有以下的定义:
class Post extends Model { public function comments() { return $this->hasMany('App\Comment'); } public function scopeApproved($q) { return $q->where('approved',true); } } class Comment extends Model { public function post() { return $this->belongsTo('App\Post'); } }
那么你可能会这样用:
$comments = Comment::whereHas('post', function($q) { $q->approved(); })->get();
这是管用的。
-
设想Post和Comment有以下的定义:
class Post extends Model { public function comments() { return $this->morphOne('App\Comment', 'commentable'); } public function scopeApproved($q) { return $q->where('approved',true); } } class Comment extends Model { public function commentable() { return $this->morphTo(); } }
那么
$comments = Comment::whereHas('commentable', function($q) { $q->approved(); })->get();
这竟然就不管用了。
十分蛋疼。有同样问题的朋友可以来讨论下。
同问
确实啊