Update: the PR has been just merged to 4.2, so now it's possible to use dot nested notation in has
methods ( ->has('relation1.relation2)
->whereHas('relation1.relation2, ..
)
Your question remains a bit unclear or you misunderstand whereHas() method as it is used to filter models (users in this case) and get only those that have related models fitting search conditions.
It seems that you want to find Packages from the context of a given User, so no need to use whereHas method.
Anyway depending on the relations (1-1,1-m,m-m) this can be easy or pretty hard and not very efficient. As I stated, loading nested relations means that for every level of nesting comes another db query, so in this case you end up with 5 queries.
Regardless of the relations you can invert this chain like this, as it will be easier:
edit: This is not going to work atm as whereHas() doesn't process dot nested relations!
// given $user and $search:
$packages = Package::where('alias','like',"%$search%")
->whereHas('product.membership.club.user', function ($q) use ($user) {
$q->whereId($user->id);
})->get();
As you can see this is much more readable, still runs 5 queries.
Also this way you get $packages, which is a single Collection of the models you wanted.
While from the context of a user you would get something like this (depending on the relations again):
$user
|-club
| |-membership
| | |-product
| | | |-packages
| | |-anotherProduct
| | | |-packages
| | |-yetAnotherProduct
| | |-packages
| |-anotherMembership
.....
You get the point, don't you?
You could fetch the packages from the Collection, but it would be cumbersome. It's easier the other way around.
So the answer to your question would be simply joining the tables:
// Let's assume the relations are the easiest to handle: 1-many
$packages = Package::where('alias','like',"%$search%")
->join('products','packages.product_id','=','products.id')
->join('memberships','products.membership_id','=','memberships.id')
->join('clubs','memberships.club_id','=','clubs.id')
->where('clubs.user_id','=',$user->id)
->get(['packages.*']); // dont select anything but packages table
Of course you can wrap it in a nice method so you don't have to write this everytime you perform such search.
Performance of this query will be definitely much better than separate 5 queries shown above. Obviously this way you load only packages, without other related models.