🎃

Laravelでリレーショナルデータが無いデータだけを取得する

2021/08/06に公開

こんにちは

今回はLaravelでリレーショナルデータがないデータだけを取得する方法について解説します。

今回の想定では、 articlescomments の2つのテーブルがあり、コメントがない記事だけを取得するのを試していこうと思います。

コメントが無い記事だけを取得する

whereDoesntHaveを使用する方法

withでcommentsも一緒に取得してから、 articleIdが一致するcommentsがないものだけを取得するというロジックです。

public function getArticlesWithoutComments(int $articleId)
{
    return Article::with("comments")->whereDoesntHave('comments')->get();
}

リレーショナルデータにもっと条件つけたい場合は、whereDoesntHaveの第二引数で条件をつけることができます。
例えばユーザーIDで条件を絞ってみます。

public function getArticlesWithoutComments(int $articleId, int $userId)
{
    return Article::with("comments")->whereDoesntHave('comments', function ($q) use ($userId) {
            $q->where('user_id', $userId);
        })->get();
}

withCountとhavingの組み合わせを使用する方法

withで条件をつけて検索結果数が0のものを取得するというロジックです。

public function getArticlesWithoutComments(int $articleId)
{
    return Article()::withCount('comments')
        ->having('comments_count', 0)
        ->get();
}

withCountをすると、リレーショナルデータのカウント数が「XXXX_count」という名前で出てくるので、それに対してhavingでカウントが0のものだけを取得するというようにしています。

withCountもwithと同じように条件をつけることができます。
先程と同様、コメントをしているuserIdで条件をつけていきましょう。

public function getArticlesWithoutComments(int $articleId, int $userId)
{
    return Article()::withCount(['comments' => function($q) use ($userId) {
        $q->where('user_id', $userId);
    }])
        ->having('comments_count', 0)
        ->get();
}

以上のような感じでリレーショナルデータがないデータを取得することができました。

Discussion