PHP
Finding Models Without Related Records Using `whereDoesntHave`
Efficiently identify and retrieve parent models that do not have any associated records for a specified relationship using Eloquent's `whereDoesntHave` method.
<?php
// app/Models/Product.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
public function reviews()
{
return $this->hasMany(Review::class);
}
}
// app/Models/Review.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Review extends Model
{
// ...
}
// Example 1: Find all products that have no reviews at all
$productsWithoutReviews = Product::whereDoesntHave('reviews')->get();
// Example 2: Find all products that have no reviews from 'customer_id' 5
$productsWithoutSpecificReviews = Product::whereDoesntHave('reviews', function ($query) {
$query->where('customer_id', 5);
})->get();
// Example 3: Find users who haven't placed any orders in the last month
// Assuming User has 'orders' relationship
// $usersWithoutRecentOrders = User::whereDoesntHave('orders', function ($query) {
// $query->where('created_at', '>', now()->subMonth());
// })->get();
How it works: The `whereDoesntHave` method is used to query for models that *do not* have any related records for a given relationship. It's the inverse of `whereHas`. This is extremely useful for scenarios like finding products that haven't received any reviews, users who haven't placed any orders, or articles without any tags. It can also accept a closure to apply specific conditions to the related model, further refining which 'missing' relationships to detect.