Laravel ORM中with,where, 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();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章