【问题标题】:Laravel: Paginate query which is ordered by a hasOne-relationshipLaravel:按 hasOne 关系排序的分页查询
【发布时间】:2021-05-23 15:34:19
【问题描述】:

我有一个包含许多联系人的客户模型。我想创建一个分页按最新联系人排序的联系人视图/列表。

客户.php

    public function contacts()
    {
        return $this->hasMany(Contact::class);
    }


    public function latestContact()
    {
        return $this->hasOne(Contact::class)->latestOfMany()->withDefault();
    }

在视图中,我想向客户展示这样的:

@foreach ($customers as $customer)

<x-table.row wire:key="row-{{ $customer->id }}">
   <x-table.cell>
      {{ $customer->last_name }}, {{ $customer->first_name }}
   </x-table.cell>
   <x-table.cell>
      {{ $customer->latestContact->contacted_at }}
   </x-table.cell>
</x-table.row>

@endforeach

表结构


Schema::create('customers', function (Blueprint $table) {
   $table->id();
   $table->foreignId('user_id');
   $table->string('first_name');
   $table->string('last_name');
});


Schema::create('contacts', function (Blueprint $table) {
   $table->id();
   $table->foreignId('user_id');
   $table->foreignId('customer_id');
   $table->string('type');
   $table->string('body');
   $table->timestamp('contacted_at');
});

我正在努力为此获得正确的查询。这是我的最后一次尝试,它给了我以下错误:

照亮\数据库\查询异常 SQLSTATE[42S22]:未找到列:1054 未知列 'latestContact.contacted_at' in 'order Clause'...

return view('livewire.dashboard', [
            'customers' => Customer::with('customers.*', 'latestContact.contacted_at')
                            ->join('contacts', 'contacts.customer_id', '=', 'customers.id')
                            ->orderBy('latestContact.contacted_at')
                            ->paginate(25)
        ]);

感谢您的支持!

【问题讨论】:

  • 为什么不直接使用属性?
  • @ChamaraAbeysekara 你到底是什么意思?能详细点吗?
  • 使用$append并有一个getLatestContactAttribute()函数返回$this-&gt;contacts-&gt;latest()
  • 我认为这不能解决我的问题。我能够附加属性。但是,我仍然无法对结果进行排序和分页。要么我使用 orderBy()-&gt;paginate() 找不到附加的列,要么我使用 get()-&gt;sortBy()-&gt;paginate() 也不起作用,因为 Collection 实例无法分页。有什么想法吗?

标签: php laravel eloquent


【解决方案1】:

我认为你应该像这样重写你的查询

 Customer::with(['contacts', 'latestContact'])
                            ->orderBy('latestContact.contacted_at')
                            ->paginate(25)

更新答案

 $customers=  Customer::with(['contacts', 'latestContact'=>function($query){

            return  $query->orderBy('contacted_at','DESC');
        }])->paginate(25);

在客户模型中,您需要修改如下关系

 public function latestContact()
    {
        return $this->hasOne(Contact::class)->withDefault();
    }
    

latestOfMany 表示该关系是较大的一对多关系的最新单个结果。

latestOfMany($column = 'id', $relation = null)

【讨论】:

  • 感谢您的快速回复。但是,不幸的是,我遇到了同样的问题: Illuminate\Database\QueryException SQLSTATE[42S22]: Column not found: 1054 Unknown column 'latestContact.contacted_at' in 'order Clause' (SQL: select * from 'customers' where ' customers'.'deleted_at' 是 'latestContact' 的空订单。'contacted_at' asc limit 25 offset 0)
  • 您确定有任何名为 latestContact 的表吗?
  • @maxiw46.can you post 数据库表结构
  • 不,没有名为 latestContact 的表。 LatestContact 只是客户模型中的一个关系,用于检索客户的最新联系人(参见上面的 Customer.php)。我可以在刀片中使用这种关系。但是,我不知道如何按 latestContact 对客户查询进行排序。
  • @maxiw46.yes 能否请您发布表格结构
猜你喜欢
  • 1970-01-01
  • 2021-07-14
  • 2019-09-16
  • 2017-04-21
  • 2022-01-22
  • 2020-10-06
  • 2015-06-10
  • 2019-05-14
  • 2020-05-12
相关资源
最近更新 更多