Posts Learn Components Snippets Categories Tags Tools new About
/

Laravel Eloquent, select only rows where the relation exists

Get to know how to select rows only when the relationship exists on Laravel

11 months ago

7 mins read

631 views

Selecting rows using Laravel Eloquent is fairly straight forward but what some people not aware of is when the table contains a relationship. Imagine having a table called "posts" and the table has a relation of one-to-many "comments" or "likes".

Query Relationship


In order to query the table with conditions that are across relation, we have to use the "has" method of the model. The code below will paginate posts that at least have one comment or likes. If the post has no comments or likes then it won't be queried.
use App\Post;

Post::has('comments')->paginate(16);
Post::has('likes')->paginate(16);
Just like the "where" method, the "has" method can accept the operator, and the total number of values a condition has to be met.
use App\Post;

// Retrieve all posts that have equal or more than 3 likes...
$posts = Post::has('likes', '>=', 3)->get();

// Retrive all post that have at least one comments and the comments have at least one like
$posts = Post::has('comments.likes')->get();

Advance Query Relationship


If you want to query the relation but it contains a fairly complex condition, you can use whereHas then specify the relationship and pass in an anonymous function. You can define any query constrain inside this function and if it's met, the "post" will return only with the relationship defined.
use App\Post;

$posts = Post::whereHas('comments', function (Builder $query) {
    $query->where('content', 'like', 'code%');
})->get();

Inverse of whereHas


For there inverse of "whereHas" you can use "doesntHave" method and the query will only retrieve model that has no "relation".
use App\Post;

$posts = Post::doesntHave('likes')->get();

Alternative Tags

If you like our tutorial, do make sure to support us by being our Patreon or buy us some coffee ☕️

)