如何在 Laravel 中使用 WhereHas 获取数据 HasMany()

How to get data HasMany() using WhereHas in Laravel

我想通过使用其模型“包”从我的table“包”中获取数据 在这个模型“包”中,它有一个名为 histories() 的 HasMany() 关系到模型“历史”

所以我只想获取有历史记录的数据

这是我的控制器

public function getIncomeMPW(Request $request)
{
    if ($request->expectsJson()) {
        $this->getSearch($request);
        $query = new Package();
        $query->with(['histories', 'items', 'items.prices', 'origin_regency', 'origin_district', 'origin_sub_district', 'destination_regency', 'destination_district', 'destination_sub_district', 'code', 'attachments']);

        $query->whereHas('histories', function (Builder $query) {
            $query->whereNotNull('partner_id');
        });

        $query->orderBy('created_at', 'desc');

        return (new Response(Response::RC_SUCCESS, $this->query->paginate(request('per_page', 15))))->json();
    }

}

这是我的包模型关系历史 HasMany()

public function histories(): HasMany
{
    return $this->hasMany(History::class, 'package_id', 'id');
}

最后是我现在显示的回复

我已经尝试使用 whereHas()、Has()、whereDoesntHave(),似乎对我的响应没有影响,有人可以帮我吗?

在您的回复中,您只是访问了看起来不同的查询。

return (new Response(Response::RC_SUCCESS, $this->query->paginate(request('per_page', 15))))->json();

使用$this->query

同时

$query = new Package();
$query->with(['histories', 'items', 'items.prices', 'origin_regency', 'origin_district', 'origin_sub_district', 'destination_regency', 'destination_district', 'destination_sub_district', 'code', 'attachments']);

$query->whereHas('histories', function (Builder $query) {
  $query->whereNotNull('partner_id');
});

$query->orderBy('created_at', 'desc');

定义 $query 而没有 $this。我希望您的 $this->getSearch($request); 定义 $this->query (因为该函数未发布在问题中,我无法判断)。因此,要么在您的回复中删除 $this - 要么将所有内容更改为 $this 并确保现在在第一行中覆盖它。

Quickfix 应该是

return (new Response(Response::RC_SUCCESS, $query->paginate(request('per_page', 15))))->json();

更新:

快速回答:更改

return (new Response(Response::RC_SUCCESS, $this->query->paginate(request('per_page', 15))))->json();

return (new Response(Response::RC_SUCCESS, $query->paginate(request('per_page', 15))))->json();

Wwhat whereHaswhereDoesntHave 函数在后台做的是他们做一个子查询比如:

Select * from packages where exists (select * from histories where CONDITIONS YOU HAVE MENTIONED)

这里的问题是,当您使用 with 方法时,您会急于加载 table 历史记录,这会增加一个额外的查询与第一个无关,例如:

Select * from histories where package_id in (1,2,3,4,5,6)

既然我们清除了它,我建议你做的是以这种方式将函数分配给变量:

$historyFunction = function ($query) {
            $query->whereNotNull('partner_id');
        };

然后在 withwhereHas[ 中调用它=35=]方法如下图:

 $query->with(['histories' => $historyFunction, otherRelations... ]);
 $query->whereHas('histories', $historyFunction);

它的作用是告诉 eloquent:当您急切加载历史记录关系时,将此条件添加到您即将进行的查询中。