Laravel Eloquent: has vs with vs whereHas?

with

with() is for eager loading, it means the relationship data is loaded at the time you query the parent model, where eager loading will alleviate the “N+1” query problem.

Example:
User -> hasMany -> Post

$users = User::with('posts')->get(); 
foreach($users as $user) {
    $user->posts; //posts is already loaded and no additional DB query is run
}

has

has() is to filter the selecting model based on a relationship. So it acts very similarly to a normal WHERE condition. If you just use has('relation') that means you only want to get the models that have at least one related model in this relation.

Example:
User -> hasMany -> Post

$users = User::has('posts')->get(); 
//only users that have at least one post are contained in the collection

whereHas

whereHas() works basically the same as has() but allows you to specify additional filters for the related model to check.

Example:
User -> hasMany -> Post

$users = User::whereHas('posts', function($builder) use ($value) {
    $builder->where('author', 'andi'); 
});

Leave a comment