Navigation

Laravel

How to Check if a Relationship `exists()` in Eloquent

Check Laravel relationship existence in 2025 using has(), whereHas(), and exists() methods. Optimize queries and avoid N+1 problems when filtering by relationships.

Table Of Contents

The Performance Problem

Loading models just to check if relationships exist wastes memory and database resources. Laravel's relationship existence methods solve this elegantly:

// SLOW - Loads all posts to check comments
$postsWithComments = Post::with('comments')->get()->filter(function ($post) {
    return $post->comments->count() > 0;
});

// FAST - Database-level existence check
$postsWithComments = Post::has('comments')->get();

// Even more specific - posts with approved comments only
$postsWithApprovedComments = Post::whereHas('comments', function ($query) {
    $query->where('approved', true);
})->get();

// Check if specific post has comments
$post = Post::find(1);
$hasComments = $post->comments()->exists(); // Returns boolean

// Count vs exists for performance
$commentCount = $post->comments()->count();     // Returns integer
$hasAnyComments = $post->comments()->exists();  // Returns boolean (faster)

Laravel Relationship Existence Methods

Each method serves different purposes for checking relationship existence:

// has() - Check if relationship exists
$usersWithPosts = User::has('posts')->get();
$usersWithMultiplePosts = User::has('posts', '>=', 5)->get();

// whereHas() - Check existence with conditions
$usersWithRecentPosts = User::whereHas('posts', function ($query) {
    $query->where('created_at', '>', now()->subDays(30));
})->get();

// doesntHave() - Opposite of has()
$usersWithoutPosts = User::doesntHave('posts')->get();

// whereDoesntHave() - Opposite of whereHas()
$usersWithoutRecentPosts = User::whereDoesntHave('posts', function ($query) {
    $query->where('created_at', '>', now()->subDays(30));
})->get();

// exists() on relationship instance
$user = User::find(1);
if ($user->posts()->exists()) {
    // User has at least one post
}

// Multiple relationship checks
$activeUsersWithRecentPosts = User::where('active', true)
    ->has('posts')
    ->whereHas('posts', function ($query) {
        $query->where('published_at', '>', now()->subWeek());
    })->get();

Advanced Relationship Existence Patterns

Complex scenarios require combining multiple existence checks:

// Nested relationships - users with posts that have comments
$usersWithCommentedPosts = User::whereHas('posts.comments')->get();

// Multiple relationship conditions
$popularAuthors = User::whereHas('posts', function ($query) {
    $query->where('views', '>', 1000);
})->whereHas('comments', function ($query) {
    $query->where('created_at', '>', now()->subMonth());
})->get();

// Conditional existence checks
$query = User::query();

if (request('has_posts')) {
    $query->has('posts');
}

if (request('has_recent_activity')) {
    $query->where(function ($q) {
        $q->has('posts')->orHas('comments');
    });
}

$users = $query->get();

// Performance tip: Use exists() for boolean checks
public function hasUnreadNotifications()
{
    return $this->notifications()->where('read_at', null)->exists();
}

// Instead of count() > 0
public function hasUnreadNotificationsSlow()
{
    return $this->notifications()->where('read_at', null)->count() > 0;
}

// Raw existence check for complex conditions
$hasComplexRelation = DB::table('users')
    ->whereExists(function ($query) {
        $query->select(DB::raw(1))
              ->from('posts')
              ->whereColumn('posts.user_id', 'users.id')
              ->where('posts.status', 'published')
              ->where('posts.views', '>', 1000);
    })->exists();

The exists() method is more efficient than count() > 0 because it stops at the first matching record. Use has() and whereHas() for filtering collections, and exists() on relationship instances for boolean checks.

Related: Laravel Collections: Beyond Basic Array Operations | Advanced Eloquent Techniques and Optimizations in Laravel | Building Multi-tenant Applications with Laravel: A Comprehensive Guide

Share this article

Add Comment

No comments yet. Be the first to comment!

More from Laravel