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();

    这竟然就不管用了。

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

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 4

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