雄辩与嵌套的地方 [英] Eloquent with nested whereHas

查看:151
本文介绍了雄辩与嵌套的地方的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我在我的模型集合中有这个 whereHas

Currently I have this whereHas in a collection of my model:

$query = self::whereHas('club', function($q) use ($search)
{
    $q->whereHas('owner', function($q) use ($search)
    {
        $q->where('name', 'LIKE', '%'. $search .'%');
    });

});

我的印象是上面的代码可以这样:

I was under the impression the code above could be as such:

$query = self::whereHas('club.owner', function($q) use ($search)
{
    $q->where('name', 'LIKE', '%'. $search .'%');    
});

我知道这已经是很多权力,但即使如此,如果我有一个嵌套关系5级深,事情会变得丑陋。

I'm aware this is already a lot of power, but even then, if I have a nested relationship 5 levels deep, things will get ugly.

更新:

在评论中表示,我最终没有让我的问题清楚,我很抱歉。

As stated in the comments, I ended up not making my question clear, I apologize.

我会尝试使用一个简单的例子,考虑 $ owner - >>会员 - >产品 - >包,现在从所有者我想搜索某个包,这将是这样的:

I will try to use a simple example, consider $owner->club->membership->product->package, now from owners I want to search a certain package, it would be something like this:

$query = self::whereHas('club', function($q) use ($search)
{
    $q->whereHas('membership', function($q) use ($search)
    {
        $q->whereHas('product', function($q) use ($search)
        {
            $q->whereHas('package', function($q) use ($search)
            {
                $q->where('alias', 'LIKE', '%'. $search .'%');
            });//package
        });//product
    });//membership
});//club

这是正确的吗?有没有快捷方式?

Is this correct? Is there a shortcut?

推荐答案

更新:公关已被合并到4.2,所以现在可以使用中的点嵌套符号具有方法( - > has('relation1.relation2) - > whereHas('relation1.relation2,..

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, .. )

您的问题还有一点不清楚或者您误解了 whereHas()方法,因为它用于过滤模型(在这种情况下是用户),并只获得那些具有适合搜索条件的相关模型的模型。

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.

您希望从给定的用户的上下文中找到,所以不需要使用whereHas方法。

It seems that you want to find Packages from the context of a given User, so no need to use whereHas method.

无论如何,根据关系(1-1,1-m,mm),这可以很容易或相当困难,效率也不高。正如我所说,加载嵌套关系意味着对于每个级别的嵌套来另一个数据库查询,所以在这种情况下你最终得到5个查询。

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.

Regar没有关系,你可以这样反转这个链,因为这将会更容易:

Regardless of the relations you can invert this chain like this, as it will be easier:

编辑:这个不会像atH那样处理点嵌套关系!

// given $user and $search:
$packages = Package::where('alias','like',"%$search%")
  ->whereHas('product.membership.club.user', function ($q) use ($user) {
    $q->whereId($user->id);
  })->get();






正如你所看到的那样,仍然运行5个查询。
这样你就可以得到$ package,这是你想要的模型的一个集合。


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 could fetch the packages from the Collection, but it would be cumbersome. It's easier the other way around.

所以你的问题的答案只是加入表:

// 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 

当然,你可以用一个很好的方法包装,所以你每次执行这样的搜索时都不得不写这个。
这个查询的性能肯定比以上显示的5个查询要好得多。显然这种方式你只加载包,没有其他相关模型。

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.

这篇关于雄辩与嵌套的地方的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆