PHP

Query Models Based on Related Model Existence

Filter parent Eloquent models by related model existence or absence using `has`, `doesntHave`, `whereHas`, and `whereDoesntHave` methods for precise querying.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    use HasFactory;

    public function reviews()
    {
        return $this->hasMany(Review::class);
    }
}

class Review extends Model
{
    use HasFactory;

    protected $fillable = ['product_id', 'rating', 'comment'];

    public function product()
    {
        return $this->belongsTo(Product::class);
    }
}

// Example usage in a controller or service:
/*
// Get products that have at least one review
$productsWithReviews = Product::has('reviews')->get();

// Get products that have no reviews
$productsWithoutReviews = Product::doesntHave('reviews')->get();

// Get products that have reviews with a specific condition (e.g., rating >= 4)
$highlyRatedProducts = Product::whereHas('reviews', function ($query) {
    $query->where('rating', '>=', 4);
})->get();

// Get products that do NOT have any reviews with a specific condition (e.g., no reviews with rating < 3)
$noLowRatedReviews = Product::whereDoesntHave('reviews', function ($query) {
    $query->where('rating', '<', 3);
})->get();

// Eager load reviews for products that have them
$productsWithReviewsAndData = Product::with('reviews')->has('reviews')->get();

// Count related models
$productsWithReviewCount = Product::withCount('reviews')->get();
foreach ($productsWithReviewCount as $product) {
    // $product->reviews_count will contain the number of reviews
}
*/
How it works: The `has` and `doesntHave` methods allow you to filter results based on the existence or absence of related models. For more complex conditions on the related models, `whereHas` and `whereDoesntHave` can be used. These methods accept a closure, enabling you to add custom constraints to the relationship query. This is incredibly useful for finding parent records based on criteria in their child records without retrieving all child records first. `withCount` can also be used to get the count of related models efficiently.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs