Merge 'With' and 'Wherehas' in Laravel 5

Merge 'with' and 'whereHas' in Laravel 5

In terms of performance you can't really optimize anything here (except if you were to move from eloquent relations to joins). With or without whereHas, two queries will be run. One to select all users another one to load the related models. When you add the whereHas condition a subquery is added, but it's still two queries.

However, syntactically you could optimize this a bit by adding a query scope to your model (or even a base model if you want to use this more often):

public function scopeWithAndWhereHas($query, $relation, $constraint){
return $query->whereHas($relation, $constraint)
->with([$relation => $constraint]);
}

Usage:

User::withAndWhereHas('submissions', function($query) use ($id){
$query->where('taskid', $id);
})->get();

Multiple orWhere() in whereHas() in Laravel 5

try this:

$query=Contact::query();
$query->whereHas('Account', function ($q) {
$q->where(function($query) {
$query->where('account_city','test2')->orWhere('account_name','test');
});
});
$query->get();

Laravel - is there a way to combine whereHas and with

If a concept of an "active program" is important in your application, consider creating a separate relation just for active programs (in this case I'm presuming you have a HasMany relation):

class Model
{
public function activePrograms()
{
return $this->hasMany(Program::class)->active();
}
}

Then you can simplify your query to:

Model::with('activePrograms')->has('activePrograms')->get();

Laravel Eloquent: whereHas on relationship involving multiple tables

I hope this would be the answer of your question.

Donation::whereHas('donator',function($query){
$query->whereHas('charities',function($query){
$query->whereIn('id',[1,2,3,4]);
})
})->get();

Laravel combining has() and whereHas()

whereHas, doesntHave etc are all methods that, in the end, call has. If you look at the signature of whereHas you can see that it allows a count to be passed as well:

public function whereHas($relation, Closure $callback, $operator = '>=', $count = 1)

So you could do that, or just use whereDoesntHave:

return $this->hasMany('App\Models\Item')->whereDoesntHave('audios', function ($q) {
$q->where('gender', 'female');
});

Laravel: Difference between whereHas and with contains constraint

As you said, With causes eager loading but doesn't restrict/filter the results.

WhereHas doesn't eager load the user model but restricts/filters the results.


Imagine a Blogs model that can have a user or not.

WhereHas will query for models with a user meeting the requirements and only return models that do.

With will query for all blog models but only include the user when it meets the requirement.

Three blog posts

id: 1
user: { id: 1, age: 25 }
title: blog post 1

id: 2
user: null
title: blog post two without user

id: 3
user: { id: 3, age: 15 }
title: blog post 2 with user low age

This

Blog::whereHas('user', function($user){
$user->where('age', '>', 21);
})->get()

will return you

id: 1
user: null
user_id: 1
title: blog post 1

While

Blog::with(['user' => function($user){
$user->where('age', '>', 21);
}])->get()

Will return you

id: 1
user: { id: 1, age: 25 }
user_id: 1
title: blog post 1

id: 2
user: null
user_id: null
title: blog post 2 without user

id: 3
user: null
user_id: 3
title: blog post 2 with user low age

You would most likely be using the two together, like this, restricted to fetch only blog posts by users over the age of 21, and eager load the user model on those, without the restriction since results are already limited for it in the whereHas.

Blog::whereHas('user', function($user){
$user->where('age', '>', 21);
})->with('user')->get();

Laravel Eloquent with 'with' and 'wherehas'

You can just do the same filtering on the with (constraining eager loading):

$creditFilter = function ($q) use ($status) {
$q->where('credit_status', $status);
};

Player::with(['photo', 'credit' => $creditFilter])
->whereHas('credit', $creditFilter)
->paginate(15);

You can save that closure and pass it to the with and whereHas so you don't have to type the same identical closure twice.

Laravel 5.6 Docs - Eloquent - Relationships - Eager Loading - Constraining Eager Loads



Related Topics



Leave a reply



Submit