如何使用 Eloquent Query Builder 在与同一个表的关系上使用 whereHas?

Har*_*tts 5 php mysql laravel eloquent

我正在尝试运行此查询:

$products = $this->product_model->where(function($query) use ($key) {
    $query->whereHas('categories', function ($category) use ($key) {
        $category->where('key', $key);
    });
    $query->orWhereHas('parent.categories', function ($category) use ($key) {
        return $category->where('key', $key);
    });
});
Run Code Online (Sandbox Code Playgroud)

父关系是另一个产品,所以它来自同一个表。我遇到的问题在于它产生的查询:

SELECT *
FROM `products`
WHERE (
    (SELECT count(*)
     FROM `categories`
     INNER JOIN `category_product` ON `categories`.`id` = `category_product`.`category_id`
     WHERE `category_product`.`product_id` = `products`.`id`
     AND `key` = 'mens'
    ) >= 1
 OR
    (SELECT count(*)
     FROM `products` AS `self_30ec5d4782a83841add518f618b9f59e`
     WHERE `self_30ec5d4782a83841add518f618b9f59e`.`id` = `products`.`parent_product_id`
     AND
         (SELECT count(*)
          FROM `categories`
          INNER JOIN `category_product` ON `categories`.`id` = `category_product`.`category_id`
          WHERE `category_product`.`product_id` = `products`.`id`
          AND `key` = 'mens'
         ) >= 1
    ) >= 1
)
Run Code Online (Sandbox Code Playgroud)

在 OR 之后的子查询中,我需要这一行:

WHERE `category_product`.`product_id` = `products`.`id`
Run Code Online (Sandbox Code Playgroud)

要这样:

WHERE `category_product`.`product_id` = `self_30ec5d4782a83841add518f618b9f59e`.`id`
Run Code Online (Sandbox Code Playgroud)

当我在数据库上运行这个 SQL 时,我得到了正确的结果:

SELECT *
FROM `products`
WHERE (
    (SELECT count(*)
     FROM `categories`
     INNER JOIN `category_product` ON `categories`.`id` = `category_product`.`category_id`
     WHERE `category_product`.`product_id` = `products`.`id`
     AND `key` = 'mens'
    ) >= 1
 OR
    (SELECT count(*)
     FROM `products` AS `self_30ec5d4782a83841add518f618b9f59e`
     WHERE `self_30ec5d4782a83841add518f618b9f59e`.`id` = `products`.`parent_product_id`
     AND
         (SELECT count(*)
          FROM `categories`
          INNER JOIN `category_product` ON `categories`.`id` = `category_product`.`category_id`
          WHERE `category_product`.`product_id` = `self_30ec5d4782a83841add518f618b9f59e`.`id`
          AND `key` = 'mens'
         ) >= 1
    ) >= 1
)
Run Code Online (Sandbox Code Playgroud)

但我不确定如何在我的 PHP 代码中做到这一点。另外,这是预期的 SQL 输出吗?它不应该做我想让它做的事情吗?由于子查询在 whereHas?

pat*_*cus 2

这是 Laravel 中的一个错误。has()/whereHas()无法正确处理自我关系或嵌套自我关系的条件。

我已提交拉取请求来纠正此问题。您可以在这里查看。

我不知道它是否会被接受,但你可以看一下它被更改的代码,并决定是否要自己手动更新 Laravel。您也可以关注并等待结果。