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。

这里就有个有趣的事情。

  1. 设想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();

    这是管用的。

  2. 设想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();

    这竟然就不管用了。

十分蛋疼。有同样问题的朋友可以来讨论下。

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 4

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!