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 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 4

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