Laravel:如何通过间接关联获取模型的latestOfMany()数据?
解决方案:获取Clerk关联的最新Invoice
方案一:利用Laravel Eloquent关联优化(推荐)
Laravel的hasOneThrough关联可以直接建立Clerk到Invoice的跨表关联,结合latestOfMany方法能高效获取最新的Invoice记录,完全避免N+1查询问题。
修改Clerk模型,添加以下关联方法:
class Clerk extends Model { public function people() { return $this->hasMany(People::class)->orderBy('Nachname', 'desc'); } // 新增:关联到当前Clerk下属所有People的最新Invoice public function latestInvoice() { return $this->hasOneThrough( Invoice::class, People::class, 'clerk_id', // People表中关联Clerk的外键 'people_id', // Invoice表中关联People的外键 'id', // Clerk表的主键 'id' // People表的主键 )->latestOfMany('date'); } }
使用方式
在控制器中预加载该关联,避免延迟加载带来的性能问题:
// 获取指定Clerk并预加载最新Invoice $clerk = Clerk::with('latestInvoice')->find($yourClerkId); // 在clerk.index.blade视图中直接调用 {{ $clerk->latestInvoice->date ?? '无记录' }}
方案二:使用查询构造器(轻量需求首选)
如果仅需要获取最新Invoice的date字段,无需完整模型实例,可以用查询构造器直接执行单次查询,性能更优:
在Clerk模型中添加访问器方法:
class Clerk extends Model { public function people() { return $this->hasMany(People::class)->orderBy('Nachname', 'desc'); } // 访问器:获取当前Clerk的最新Invoice日期 public function getLatestInvoiceDateAttribute() { return Invoice::query() ->join('people', 'people.id', '=', 'invoices.people_id') ->where('people.clerk_id', $this->id) ->latest('date') ->value('date'); // 直接返回date字段值,无多余数据 } }
使用方式
在视图中直接调用访问器:
{{ $clerk->latest_invoice_date ?? '无记录' }}
原代码问题说明
你之前的循环查询会触发N+1查询问题:1次查询获取所有People,再循环每个People执行1次Invoice查询,当People数量较多时,数据库请求会急剧增加,导致性能大幅下降。上述两种方案均通过单次查询或预加载解决了这个问题。
内容的提问来源于stack exchange,提问作者Tobi
相关产品推荐
相关产品推荐

