laravel eloquent with, has whereHas 的区别

文章目录

    共同之处,这三个函数的参数,都是 model 中的 relationship function 的名字。

    • 1 对 N
    • N 对 N

    with

    类似于 SQL 中的 left join。左侧数据会全部显示。

    with 是 eager loading,即预加载关系数据。

    has

    类似于 SQL 中的 inner join。

    当右侧有数据时才会显示。

    注意,has 跟 whereHas 并不返回关系数据。

    whereHas

    inner join 之后,可以补充查询条件

    whereHas 实际应用场景

    例如,backpack 中的 N 对 N 关系的过滤,使用 whereHas

    $this->crud->addFilter([ // select2_multiple filter
      'name' => 'roles',
      'type' => 'select2_multiple',
      'label'=> '角色'
    ], function() { // the options that show up in the select2
    	return Role::all()->pluck('name', 'id')->toArray();
    }, function($values) { // if the filter is active
    	foreach (json_decode($values) as $key => $value) {
    		$this->crud->query = $this->crud->query->whereHas('roles', function ($query) use ($value) {
    			$query->where('role_id', $value);
    		});
    	}
    });
    
    
    if(!request('roles')){
    	 $this->crud->addClause('whereHas', 'roles');
    }
    
    $users = User::whereHas('posts', function($q){
        $q->where('created_at', '>=', '2015-01-01 00:00:00');
    })->get();
    

    with 的实际应用

    但是 with 的条件查询,并没有启动过滤左侧连表的作用,只会使右侧连表显示为 null。
    所以是典型的 left join。

    例如,下面语句,还是会显示所有的发帖,而不是 is_master 的发帖。

    $items = Post::with(["user" => function($q){
        $q->where('is_master', 1);
    }])->where('category_id', $category_id)
        ->where('status', 1)
        ->orderBy('id', 'desc')
        ->offset($offset)
        ->limit($limit)
        ->get();
    

    所以,这种情况下,应该使用 whereHas.

    注意

    • whereHas 跟 with 的语法不一致
    • whereHas 和 has 并不返回关系数据,但是 with 是返回的。所以,当要返回关系数据时,两者要结合使用。
      $items = Post::whereHas("user", function($q){ $q->where('is_master', 1); })->with(['user' => function($q) { $q->where('is_master', 1); }])->where('status', 1) ->where('top', 0) ->orderBy('id', 'desc') ->offset($offset) ->limit($limit) ->get();

    参考

    https://stackoverflow.com/questions/30231862/laravel-eloquent-has-with-wherehas-what-do-they-mean

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式