【问题标题】:Laravel Eloquent nested whereHas returns everythingLaravel Eloquent 嵌套 whereHas 返回所有内容
【发布时间】:2021-08-31 04:07:32
【问题描述】:

我有这个关系表:

-categories (has many products)
-products (has many features)
-features

我试图使用它的 slug 获得一个特殊的类别,并获得类别中的产品,我还想使用(id)通过某些功能过滤产品

我的代码:

$category = Category::whereHas('products', function ($query) {
    $query->whereHas('features', function ($query2) {
        $query2->where('id', 21); // Example id (products where has features with '21' id)
    });
})->where('slug', 'category-slug')
  ->with('products:id,title', 'products.features')->get();

但代码会返回包含所有产品的该类别(有或没有 id 为 21 的功能)

解决办法是什么?

【问题讨论】:

  • 代码只是在使用变量时不执行$query2 条件,还是在硬编码时也不运行?
  • @MuhamadRafiPamungkas 是的。在每种模式下它都不起作用,它将返回类别中的所有产品

标签: php mysql laravel eloquent


【解决方案1】:

您可能想试试dot notation

$category = Category::whereHas('products.features', function ($query) {
        $query->whereKey(21);
    })
    ->where('slug', 'category-slug')
    ->with('products:id,title', 'products.features')->get();

【讨论】:

  • 不幸的是,它仍然返回所有具有所有功能的产品(带或不带 21 id)
  • @K1-Aria 点符号应该像documentation 所说的那样工作。这样做,而不是运行 ->get() 将其替换为 ->toSql() 并在此处与我们分享结果。
【解决方案2】:

我认为最好使用存储产品功能的数据透视表。

+------------------+
| categories       |
| features         |
| feature_product  |
| products         |
+------------------+

请注意,数据透视表名称应在 Laravel 约定之前按字母顺序排列。

feature_product 的列:

+------------+---------+------+-----+---------+----------------+
| Field      | Type    | Null | Key | Default | Extra          |
+------------+---------+------+-----+---------+----------------+
| id         | int(11) | NO   | PRI | NULL    | auto_increment |
| product_id | int(11) | YES  |     | NULL    |                |
| feature_id | int(11) | YES  |     | NULL    |                |
+------------+---------+------+-----+---------+----------------+

现在添加与您的产品模型的关系:

public function features() {
    return $this->belongsToMany(Feature::class);
}

查询:

$products = Product::select()
        ->join('feature_product', function ($join) {
            $join->on('feature_product.product_id', 'products.id')
                ->where('feature_id', 21);
        })
        ->join('categories', function ($join) {
            $join->on('products.category_id', 'categories.id')
                ->where('slug', 'slug-name');
        }) 
        ->get();

现在获取每个产品的功能:

foreach ($products as $product) {
         $product->features;
}

【讨论】:

    猜你喜欢
    • 2021-08-23
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    • 2019-02-26
    • 2015-11-04
    • 2019-12-28
    • 2017-06-09
    • 2020-09-16
    相关资源
    最近更新 更多