本篇主要是要探討,with/has/whereHas/doesntHave/whereDoesntHave之間的差別,以部落格文章及留言一對多的例子來看。
資料情境:


文章1有2則留言,文章2有1則留言,文章3則沒有留言。
程式碼與結果:



$with_result = Article::with('comments')->get();

$has_result = Article::has('comments')->get();

has是把所有有留言的文章找出來,不帶出留言。
$has_with_result = Article::has('comments')->with('comments')->get();

has+with是把所有有留言的文章找出來,帶出留言。
$whereHas_result = Article::whereHas('comments', function($q){
$q->where('create_datetime', '>=', '2022-04-02 00:00:00');
})->get();

whereHas找出所有有留言&任一留言有create_datetime >= 2022-04-02 00:00:00的文章。
$doesntHave_result = Article::doesntHave('comments')->get();

doesntHave找出所有沒有留言的文章。
$whereDoesntHave_result_1 = Article::whereDoesntHave('comments', function($q){
$q->where('create_datetime', '>=', '2022-04-02 00:00:00');
})->get();

找出所有沒有留言or 所有留言create_datetime皆非>=2022-04-02 00:00:00的文章。
$whereDoesntHave_with_result_1 = Article::whereDoesntHave('comments', function($q){
$q->where('create_datetime', '>=', '2022-04-02 00:00:00');
})->with('comments')->get();

whereDoesntHave+with 同上,只是把留言也找出來。
$whereDoesntHave_result_2 = Article::whereDoesntHave('comments', function($q){
$q->where('create_datetime', '<=', '2022-04-02 00:00:00');
})->get();

whereDoesntHave找出所有沒有留言or 所有留言create_datetime皆非<=2022-04-02 00:00:00的文章。
本筆記參考:
1. https://blog.csdn.net/qq_32439101/article/details/81449190
2. https://stackoverflow.com/questions/30231862/laravel-eloquent-has-with-wherehas-what-do-they-mean
3. https://laravel.com/docs/9.x/eloquent-relationships