【问题标题】:I don't understand how works function (Builder $query) in Laravel我不明白 Laravel 中的功能(Builder $query)是如何工作的
【发布时间】:2019-10-08 08:43:22
【问题描述】:

我有以下功能可以从我的表Product_Colors 中查找具有相同颜色的产品,并且工作正常:

$colors = ProductColor::query()->
select('color_id', DB::raw("count(*) as amount"))
    ->groupBy('color_id')
    ->having('amount','>=', '3')
    ->get();

而且我有多对多的关系:

public function colors() {
   return $this->belongsToMany('App\Color','product_colors');
}

现在我想获得所有具有相同 3 种颜色的产品。 我有这个问题:

$products = Product::whereHas('colors', function(Builder $query) { $query
    ->groupBy('color_id', 'product_id');},'>', '3')->get();

我什么也没得到,但我确信我有两种颜色相同的产品。有人可以帮助我,提示我做错了什么吗?

我有以下代码来获取所有超过 3 种颜色的项目:

        $products = Product::has('colors', '>', 3)->with('colors')->get();

但我需要所有颜色超过 3 种颜色完全相同的颜色 例如:

    "products": [
    {
        "id": 2,
        "title": "net",
        "created_at": "2019-10-08 07:36:42",
        "updated_at": "2019-10-08 07:36:42",
        "colors": [
            {
                "id": 16,
                "name": "Peru",
                "created_at": "2019-10-08 07:36:42",
                "updated_at": "2019-10-08 07:36:42",
                "pivot": {
                    "product_id": 2,
                    "color_id": 16
                }
            },
            {
                "id": 17,
                "name": "Red",
                "created_at": "2019-10-08 07:36:42",
                "updated_at": "2019-10-08 07:36:42",
                "pivot": {
                    "product_id": 2,
                    "color_id": 17
                }
            },
            {
                "id": 20,
                "name": "DarkTurquoise",
                "created_at": "2019-10-08 07:36:42",
                "updated_at": "2019-10-08 07:36:42",
                "pivot": {
                    "product_id": 2,
                    "color_id": 20
                }
            },
            {
                "id": 2,
                "name": "MediumPurple",
                "created_at": "2019-10-08 07:36:42",
                "updated_at": "2019-10-08 07:36:42",
                "pivot": {
                    "product_id": 2,
                    "color_id": 2
                }
            }
        ]
    },
    {
        "id": 3,
        "title": "org",
        "created_at": "2019-10-08 07:36:42",
        "updated_at": "2019-10-08 07:36:42",
        "colors": [
            {
                "id": 2,
                "name": "MediumPurple",
                "created_at": "2019-10-08 07:36:42",
                "updated_at": "2019-10-08 07:36:42",
                "pivot": {
                    "product_id": 3,
                    "color_id": 2
                }
            },
            {
                "id": 16,
                "name": "Peru",
                "created_at": "2019-10-08 07:36:42",
                "updated_at": "2019-10-08 07:36:42",
                "pivot": {
                    "product_id": 3,
                    "color_id": 16
                }
            },
            {
                "id": 17,
                "name": "Red",
                "created_at": "2019-10-08 07:36:42",
                "updated_at": "2019-10-08 07:36:42",
                "pivot": {
                    "product_id": 3,
                    "color_id": 17
                }
            },
            {
                "id": 20,
                "name": "DarkTurquoise",
                "created_at": "2019-10-08 07:36:42",
                "updated_at": "2019-10-08 07:36:42",
                "pivot": {
                    "product_id": 3,
                    "color_id": 20
                }
            }
        ]
    },

【问题讨论】:

  • “所有具有超过 3 种颜色且颜色完全相同的颜色”背后的逻辑是什么,如果有两组满足此条件的颜色会发生什么?
  • 这是我的任务。这段代码没有继续逻辑。这只是一个了解更好的 laravel 查询构建器的练习

标签: mysql laravel query-builder


【解决方案1】:

我认为你不能像这样对你的 where 子句提供检查。

所以试试这个吧:

$products = Product::whereHas('colors', function(Builder $query) 
    { 
        $query->groupBy('color_id', 'product_id')
              ->havingRaw('count(color_id) > 3');
    })
    ->with('colors') // eager load them
    ->get();

它可能不起作用,因为我无法尝试,但我希望它至少能让您了解如何执行此操作。

否则在collection 实例上使用过滤器。

所以可能是这样的:

$products = Product::has('colors')->with('colors') 
    ->get()
    ->filter(function($item) {
        return $item->colors->count() >= 3;
    });

【讨论】:

  • 这行代码不需要->with('colors') // eager load them,因为 laravel 会急切地从幕后加载颜色。我自己测试过。
  • @kellymandem laravel 不会自行加载它们,要么你已经加载了它们,要么你不了解预先加载的工作原理。检查laravel.com/docs/5.8/eloquent-relationships#eager-loading
  • 第二种解决方案(对集合进行过滤)对于没有经验的开发人员来说是个坏建议。你应该删除它。
  • @N69S 我已经使用Laravel 5.5 sample blog project 使用poststags 之间的关系对我自己的数据进行了尝试,并且使用相同的查询构建器流程可以很好地加载标签。跨度>
  • @kellymandem 为此您需要在模型上设置属性protected $eagerload。无论如何,这里不是讨论这个的地方,你可以和我一起chat.stackoverflow.com/rooms/200552/laravel-eager-loading 讨论这个
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多