使用相关模型的计数加载 laravel eloquent 模型
Load laravel eloquent model withCount of related model
鉴于我有两个 eloquent 模型:预订和客户。
当我列出所有预订以及相应客户时,我还想显示相应客户的总预订量(此预订数 + 所有其他预订数)。
示例输出:
- 预订 1:客户 A(总共有 20 个预订)
- 预订 2:客户 B(总共有 10 个预订)
- Booking3:客户 C(VIP:总共有 100 个预订)
为了避免 n+1 问题(显示此信息时每次预订需要额外查询一次),我想为客户加载 bookingsCount
。
关系是:
预订:public function customer() { return $this->belongsTo(Customer::class) }
客户:public function bookings() { return $this->hasMany(Booking::class) }
使用预先加载查询预订的示例
工作,但没有提前加载 bookingsCount:
Booking::whereNotCancelled()->with('customer')->get();
不工作:
Booking::whereNotCancelled()->with('customer')->withCount('customer.bookings')->get();
我了解到,您不能在相关模型的字段上使用 withCount
,但您可以创建一个 hasManyThrough
关系并在该关系上调用 withCount
,例如Booking::whereNotCancelled()->withCount('customerBookings');
().
但是:这不起作用。我想,这是因为一个预订属于一个客户,而一个客户有许多预订。
这是 class Booking
的 hasManyThrough 关系
public function customerBookings()
{
// return the bookings of this booking's customer
return $this->hasManyThrough(Booking::class, Customer::class);
}
这是 hasManyThrough
的失败测试
/**
* @test
*/
public function it_has_a_relationship_to_the_customers_bookings()
{
// Given we have a booking
$booking = factory(Booking::class)->create();
// And this booking's customer has other bookings
$other = factory(Booking::class,2)->create(['customer_id' => $booking->customer->id]);
// Then we expect the booking to query all bookings of the customer
$this->assertEquals(3, Booking::find($booking->id)->customerBookings()->count());
}
报错
no such column: customers.booking_id (SQL: select count(*) as aggregate from "bookings" inner join "customers" on "customers"."id" = "bookings"."customer_id" where "customers"."booking_id" = efe51792-2e9a-4ec0-ae9b-a52f33167b66)
不足为奇。没有这样的列 customer.booking_id
。
问题
在这种情况下,预期的行为是否可能?如果是这样,我将如何急切加载预订客户的预订总数?
试试这个:
public function customer() {
return $this->belongsTo(Customer::class)->withCount('bookings');
}
Booking::whereNotCancelled()->with('customer')->get();
鉴于我有两个 eloquent 模型:预订和客户。
当我列出所有预订以及相应客户时,我还想显示相应客户的总预订量(此预订数 + 所有其他预订数)。
示例输出:
- 预订 1:客户 A(总共有 20 个预订)
- 预订 2:客户 B(总共有 10 个预订)
- Booking3:客户 C(VIP:总共有 100 个预订)
为了避免 n+1 问题(显示此信息时每次预订需要额外查询一次),我想为客户加载 bookingsCount
。
关系是:
预订:public function customer() { return $this->belongsTo(Customer::class) }
客户:public function bookings() { return $this->hasMany(Booking::class) }
使用预先加载查询预订的示例
工作,但没有提前加载 bookingsCount:
Booking::whereNotCancelled()->with('customer')->get();
不工作:
Booking::whereNotCancelled()->with('customer')->withCount('customer.bookings')->get();
我了解到,您不能在相关模型的字段上使用 withCount
,但您可以创建一个 hasManyThrough
关系并在该关系上调用 withCount
,例如Booking::whereNotCancelled()->withCount('customerBookings');
(
但是:这不起作用。我想,这是因为一个预订属于一个客户,而一个客户有许多预订。
这是 class Booking
的 hasManyThrough 关系public function customerBookings()
{
// return the bookings of this booking's customer
return $this->hasManyThrough(Booking::class, Customer::class);
}
这是 hasManyThrough
的失败测试/**
* @test
*/
public function it_has_a_relationship_to_the_customers_bookings()
{
// Given we have a booking
$booking = factory(Booking::class)->create();
// And this booking's customer has other bookings
$other = factory(Booking::class,2)->create(['customer_id' => $booking->customer->id]);
// Then we expect the booking to query all bookings of the customer
$this->assertEquals(3, Booking::find($booking->id)->customerBookings()->count());
}
报错
no such column: customers.booking_id (SQL: select count(*) as aggregate from "bookings" inner join "customers" on "customers"."id" = "bookings"."customer_id" where "customers"."booking_id" = efe51792-2e9a-4ec0-ae9b-a52f33167b66)
不足为奇。没有这样的列 customer.booking_id
。
问题
在这种情况下,预期的行为是否可能?如果是这样,我将如何急切加载预订客户的预订总数?
试试这个:
public function customer() {
return $this->belongsTo(Customer::class)->withCount('bookings');
}
Booking::whereNotCancelled()->with('customer')->get();