Let's say I have a model Foobar with relationships named baz and quux. Foobar belongsTo Baz and Baz hasOne Foobar. This means there is a foreign key column in the Foobar table for baz_id. The relationships are defined correctly in the models. In case it is relevant, this model caching library is used on both models: https://github.com/GeneaLabs/laravel-model-caching
I would like to query all Foobar that do not have either relationship; meaning I only want to select Foobar where BOTH baz and quux relationships are absent. I do so as follows:
Foobar::doesntHave('baz', 'AND')->doesntHave('quux')->get();
Now let's say $foobar is a Foobar instance with no relationships, and $baz is a freshly created Baz instance. I associate the two like so:
$baz->foobar()->associate($foobar);
$baz->save();
Now, I run the above query again. The row represented by $foobar is still appearing in the results, even though it shouldn't since it now has a non-null baz relationship. My question is: why is this happening, and how can I fix it?
I played around in artisan console while debugging this. In the same artisan session:
Foobar::doesntHave('baz', 'AND')->doesntHave('quux')->get();
// This gets a collection that is not empty, the first item is a Foobar instance that definitely has a baz
Foobar::doesntHave('baz', 'AND')->doesntHave('quux')->first();
// This is null (?)
Foobar::doesntHave('baz', 'AND')->doesntHave('quux')->count();
// This is 0 (?)
Foobar::doesntHave('baz', 'AND')->doesntHave('quux')->get()->get(0)->baz;
// This gets the Baz object attached to the first instance
To double-check that the SQL is correct:
Foobar::doesntHave('baz', 'AND')->doesntHave('quux')->get()->toSql();
// This outputs the generated raw SQL.
I input the raw SQL into a SQL client and got the correct result.
I also attempted / checked while debugging:
$foobar->touch()- did not change results.- Made sure API endpoint was not cached by browser, Cloudflare, or anything else