Here we will see working with Eloquent relationships; it’s common to filter parent records based on their related data. Laravel provides the whereHas() method for this, but there’s a small problem that many developers encounter.

Suppose you want to retrieve users who have published posts and also display only those published posts. Using whereHas() alone filters the users correctly, but when you access the relationship, Laravel still loads all of the user’s posts unless you apply the same condition again using with().
Laravel solves this problem with the withWhereHas() method.
Prerequisites
- Composer (Latest Version)
- Laravel 12
Steps to use withWhereHas() in Laravel 12
- Create a new Laravel project
- models and migration
- Define the relationship
- Create routes
- Create a controller
- Test the output
Step 1: Create a New Laravel Project
composer create-project laravel/laravel withwherehas-demoStep 2: Create Models and Migration
php artisan make:model Post -mUpdate the posts migration.
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->string('title');
$table->enum('status', ['draft', 'published']);
$table->timestamps();
});Run the migration.
php artisan migrateStep 3: Define the Relationship
Now, open the User model, and edit as below,
public function posts()
{
return $this->hasMany(Post::class);
}Now open the Post model.
public function user()
{
return $this->belongsTo(User::class);
}After that, add the dummy data.
Step 4: Create Routes
use App\Http\Controllers\UserController;
Route::get('/users', [UserController::class, 'index']);Step 5: Create a Controller
php artisan make:controller UserControllerNow open the controller and edit it as follows,
<?php
namespace App\Http\Controllers;
use App\Models\User;
class UserController extends Controller
{
public function index()
{
$users = User::withWhereHas('posts', function ($query) {
$query->where('status', 'published');
})->get();
return response()->json($users);
}
}Step 6: Test the Output
To see the output, you need to open the browser:
http://127.0.0.1:8000/users
You will get the result as below.
[
{
"id": 1,
"name": "test user",
"email": "user@gmail.com",
"posts": [
{
"id": 1,
"title": "Laravel Post",
"status": "published",
"user_id": 1
}
]
}
]Conclusion:
The withWhereHas() method is a convenient way to combine the functionality of whereHas() and with() into a single query.

FAQ
1. What is withWhereHas() in Laravel?
withWhereHas() is an Eloquent method that combines whereHas() and with() into a single query. It filters parent models based on relationship conditions while eager loading only the matching related records.
2. Is withWhereHas() better than using whereHas() and with() separately?
Yes. It provides the same functionality with less code, making your queries cleaner, easier to maintain, and less prone to errors.
3. Is withWhereHas() available in Laravel 12?
Yes. withWhereHas() is fully supported in Laravel 12 and is recommended whenever you need to filter and eager load the same relationship using identical conditions.



