【问题标题】:How to order by another table join by eager loading in Laravel如何通过在 Laravel 中通过预先加载来通过另一个表连接进行排序
【发布时间】:2013-11-26 11:34:10
【问题描述】:

我有产品和库存表;

产品

id int
name varchar
created_at timestamp

股票

id int
name varchar
product_id varchar
created_at timestamp

产品型号

public function validStock() {
    return $this->hasMany('Stock')->where('quantity', '>', 10);
}

如果两者都有created_at,如何按股票的created_at排序,我试过两种方法都不行

Product::with('validStock')->orderBy('validStock.created_at', 'DESC');

Product::with(array('validStock' => function($q) {
    $q->orderBy('created_at', 'DESC');
}));

【问题讨论】:

标签: laravel-4


【解决方案1】:

您可以使用连接,而不是在检索所有数据后进行排序(在对结果进行分页时不可能以有效的方式进行)。

(此答案基于this one。)

Product::with('validStock')
    ->join('stocks', 'stocks.product_id', '=', 'products.id')
    ->select('products.*') // Avoid selecting everything from the stocks table
    ->orderBy('stocks.created_at', 'DESC')
    ->get();

我唯一不喜欢的是它带走了一些数据库抽象,因为你必须在这里写你的表名。

请注意,我没有在这个方向上尝试使用 hasMany 关系,就像您在示例中那样(选择产品,每个产品都有很多库存)。我只在另一个方向上尝试过 hasMany(例如,选择股票,每只股票都有一个产品)。

【讨论】:

    【解决方案2】:

    在 Laravel 中查询急切加载的关系时,您不能应用订单。您可以在执行查询后订购集合。

    $products = Product::with(array('validStock'))
        ->get()
        ->each(function ($product)
        {
            $product->validStock = $product->validStock
                ->sortBy(function ($validStock)
                {
                    return $validStock->created_at;
                })
                ->reverse();
        });
    

    【讨论】:

      【解决方案3】:

      你应该在闭包中返回 $q:

      Product::with(array('validStock' => function($q) {
          return $q->orderBy('created_at', 'DESC');
      }));
      

      【讨论】:

      • 这在我的测试中似乎没有任何作用。你能扩展一下吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-09
      • 2015-03-26
      相关资源
      最近更新 更多