Ali
Ali

Reputation: 347

whereDoesntHave not working with hasMany relationship as expected

Each target has many certs.

certs
target_id uploaded
1         1
1         0

I want to get targets that do not have any uploaded certs (uploaded = 0). The following query still return target 1 while it should return nothing!

Target::whereDoesntHave('certs', function ($query) { 
    $query->where('uploaded', 0);
})->get();

and the query that laravel produce is:

SELECT * FROM `targets`
WHERE NOT EXISTS (
    SELECT * FROM `certs`
    WHERE `targets`.`id` = `certs`.`target_id` AND `uploaded` = 0
)

Upvotes: 0

Views: 353

Answers (2)

John Lobo
John Lobo

Reputation: 15319

You can try with doesntHave

  Target::doesntHave('certs','and', function ($query) { $query->where('uploaded', 0); })->get()

Updated

 Target::with(['certs'])->whereHas('certs', function ($query) { $query->where('uploaded', 0); })->get()

Upvotes: 1

Rwd
Rwd

Reputation: 35180

Your current query is fetching all Targets that don't have any non-uploaded certs i.e. where doesn't have certs where upload is 0.

You should be able to get what you want by changing 0 to 1 i.e. get all targets that don't have any uploaded certs:

Target::whereDoesntHave('certs', function ($query) {
    $query->where('uploaded', 1);
})->get();

Upvotes: 0

Related Questions