eloquent 将所有 ID 传递给作用域,而不是当前 ID

eloquent passing all IDs to scope, not the current one

我认为有 2 个循环:

        @foreach($products as $product)

           ...

                @foreach($product->pricesOrder() as $price)

                ...

                @endforeach

           ...

        @endforeach

我的产品模型中的 pricesOrder() 范围如下:

public function scopePricesOrder($query)
{
    $product = $query->first();

    $prices = Price::join('sites as site', 'site.id', '=', 'prices.site_id')
   ->orderBy('site.order', 'asc')
   ->select('prices.*')
   ->where('product_id', $product->id)
   ->get();
}

我遇到的问题是传递给范围的查询是所有产品,而不是单个产品。

或者至少我认为这是正在发生的事情,因为循环的结果是所有行输出完全相同,即第一个行的内容,这意味着始终向范围发送相同的 productID。即使每个产品 ID 都不同且不重复。

我曾假设,因为在 $product 上调用了 pricesOrder(),所以它只会打赌获取对单个产品的查询。不是所有的人。

运行 dd($product); 范围内将 return 所有产品,而不是当前产品。

移除作用域,使用 Product.php 模型中的正常方法

public function pricesOrder()
{
    $prices = Price::join('sites as site', 'site.id', '=', 'prices.site_id')
       ->orderBy('site.order', 'asc')
       ->select('prices.*')
       ->where('product_id', $this->id)
       ->get();

    return $prices;
}

好吧,似乎有多种方法可以实现您的目标。

1: 将其设为静态函数,并将产品id作为参数传递,并使用Product::scopePricesOrder($product_id):

获取查询结果
`public static function scopePricesOrder($product_id)
{
    $prices = Price::join('sites as site', 'site.id', '=', 'prices.site_id')
   ->orderBy('site.order', 'asc')
   ->select('prices.*')
   ->where('product_id', $product_id)
   ->get();
}`

2: 只需将产品id传递给scope函数,然后使用$product->priceOrder()

获取查询结果
`public function scopePricesOrder($query, $product_id)
{
    $prices = Price::join('sites as site', 'site.id', '=', 'prices.site_id')
   ->orderBy('site.order', 'asc')
   ->select('prices.*')
   ->where('product_id', $product_id)
   ->get();
}`

3:如果您只是想使用当前的产品 ID,Ezra 的答案就可以了。

作用域应该使您的查询代码可读且灵活,而不是 return 一些相关数据。所以不要在这里使用范围,而是使用你的 'simple method' 或者创建关系:

// Product model
public function pricesOrdered($direction = 'asc')
{
   $direction = ($direction == 'desc') ? 'desc' : 'asc';

   return $this->hasMany('Price')
     ->join('sites', 'sites.id', '=', 'prices.site_id')
     ->select('prices.*')
     ->orderBy('sites.order', $direction);
}

然后你可以像任何关系一样使用它:

foreach ($product->pricesOrdered as $price)

// and reverse the order if necessery
foreach ($product->pricesOrdered('desc')->get() as $price)