DEV Community

Cover image for Laravel WhereHas() and With()

Laravel WhereHas() and With()

Othmane Nemli on July 06, 2021

Quick recall: When accessing Eloquent relationships as properties, the related models are "lazy loaded". This means the relationship dat...
Collapse
 
hoangmoli profile image
HoangMoli • Edited

The macro should be

Builder::macro(
    'withWhereHas',
    function ($relation, $constraint) {
        return $this
            ->whereHas($relation, $constraint)
            ->with($relation, $constraint);
    }
);
Enter fullscreen mode Exit fullscreen mode

if not using lambda

Collapse
 
usamaxyz profile image
usamaxyz

Thanks. I solved the same problem with inner join which supposed to be more performance efficient.

Collapse
 
brunodiaz profile image
bdiazc90

Hello! 👋
JOIN could has better performance than WHERE EXISTS (with - eager loading), BUT:

The reason to use WITH, is for accessing models as related objects (with all their fields) instead of access a couple of fields specified in JOIN.

Collapse
 
othmane_nemli profile image
Othmane Nemli

Great, would you please share your Macro?

Collapse
 
jovialcore profile image
Chidiebere Chukwudi • Edited

Thanks for sharing. Worthy to note that laravel now has withWhereHas eloquent method by default

Unlike in your case, where withWhereHas is a scope.

Collapse
 
quyle92 profile image
quyle92

thanks for great article.
Now I know that with the withWhereHas() I can load the relationship with specific condition.

Collapse
 
zensabbah profile image
zensabbah

Hi Othmane Nemli, thanks for your article.
I have one doubt though, I didn't understand why you use the whereHas query if you just specified the condition in the first query.
Don't you get the desired result only with the "with" query+condition?

Thanks in advance

Collapse
 
othmane_nemli profile image
Othmane Nemli

Thanks for reading the article.

Well, using same condition in with() and whereHas() is to prevent N+1 and get only data that you asked for in the whereHas(), so as I demonstrate the issue that we may face, the solution was to combine with() and whereHas() with same condition ..

Collapse
 
maprangsoft profile image
Maprangsoft

i use laravel 8 use \Illuminate\Database\Eloquent\Builder\Eloquent; not found

Collapse
 
othmane_nemli profile image
Othmane Nemli

Thank you, I fixed the class name, you need to use Illuminate\Database\Eloquent\Builder instead

Collapse
 
maprangsoft profile image
Maprangsoft

thank you very much.

Collapse
 
stalinwesley profile image
StalinWesley

thanks