【问题标题】:Laravel: eloquent orderBy hasOne relation column using with and whereHasLaravel:雄辩的 orderBy hasOne 关系列使用 with 和 whereHas
【发布时间】:2022-01-27 07:29:15
【问题描述】:

我有一个模型 Product 和一个 hasOne 关系方法 getCompany()

public function getCompany(){
    return $this->hasOne(Company::class, 'id', 'company_id');
}

我需要检索按getCompany.rate排序的Product集合

我的方法


$products = Product::with('getCompanyName', 'getCompany')
    ->whereHas('getCompany', function ($query) {
        return $query->where('status_shop_id', '=', 2);
    })
    ->whereHas('getCompany', function ($query) {
        return $query->where('status', '=', 1);
    })
    ->where('name', 'Like', "%$text%")
    ->whereStatus(1)
    ->whereTypeId(1)
    ->orderBy('rate', 'desc')
    ->limit(5)
    ->get();

失败:

SQLSTATE[42S22]:未找到列:1054 未知列 'getCompany.rate' 在“订单子句”中

我已经尝试在收集后对其进行排序

return $products->sortBy('getCompany.rate');

但这根本不排序

【问题讨论】:

  • 如果您想根据另一个表的列进行排序,最好使用joins。
  • @user3532758 你能告诉我吗?

标签: php laravel


【解决方案1】:

如果要根据关系的内容进行排序,则必须这样做after the fact。关系在主模型中显示为对象,并单独获取,因此您不能指望在数据库级别进行。

也无需重复whereHas 两次;您可以将这两个条件都放在回调中。

$products = Product::with('getCompanyName', 'getCompany')
    ->whereHas('getCompany', function ($query) {
        $query->where('status_shop_id', '=', 2)->where('status', '=', 1);
    })
    ->where('name', 'Like', "%$text%")
    ->whereStatus(1)
    ->whereTypeId(1)
    ->limit(5)
    ->get();
$sorted = $products->sortByDesc('getCompany.rate');

一个简单的测试将证明这是有效的:

$coll = collect([
    ["name" => "item 1", "relation" => ["size" => 23]],
    ["name" => "item 2", "relation" => ["size" => 16]],
    ["name" => "item 3", "relation" => ["size" => 15]],
    ["name" => "item 4", "relation" => ["size" => 42]],
]);
dump($coll->sortBy('relation.size'));

输出:

=> Illuminate\Support\Collection {#12167
     all: [
       2 => [
         "name" => "item 3",
         "relation" => [
           "size" => 15,
         ],
       ],
       1 => [
         "name" => "item 2",
         "relation" => [
           "size" => 16,
         ],
       ],
       0 => [
         "name" => "item 1",
         "relation" => [
           "size" => 23,
         ],
       ],
       3 => [
         "name" => "item 4",
         "relation" => [
           "size" => 42,
         ],
       ],
     ],
   }

【讨论】:

    【解决方案2】:

    如果您想根据另一个表的列进行排序,最好使用联接。

    @user3532758 你能告诉我吗?

    试试这样的:

    DB::table('products') //can use Product::join(...) as well and can attach your relationships too, just make sure necessary ids are in the select statement
    ->join('companies', 'products.id', '=', 'companies.product_id')
    ->select('products.*', 'companies.name', 'companies.rate')
    ->orderBy('companies.rate', 'desc')
    ->get();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-22
      • 1970-01-01
      • 2018-01-11
      • 2018-04-02
      • 1970-01-01
      • 2018-05-12
      • 1970-01-01
      • 2021-07-27
      相关资源
      最近更新 更多