使用相关模型的Count加载laravel eloquent模型

Tho*_*axl 3 php eager-loading laravel eloquent

鉴于我有两个雄辩的模型:预订和客户。

当我将所有预订与相应客户一起列出时,我还想显示相应客户的总预订量(此预订的数量 + 所有其他预订)。

示例输出:

  • 预订 1:客户 A(总共有 20 个预订)
  • 预订2:客户B(总共有10个预订)
  • 预订3:客户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();
Run Code Online (Sandbox Code Playgroud)

不工作:

Booking::whereNotCancelled()->with('customer')->withCount('customer.bookings')->get();
Run Code Online (Sandbox Code Playgroud)

我了解到,您不能withCount在相关模型的字段上使用,但您可以创建一个hasManyThrough关系并调用withCount该关系,例如Booking::whereNotCancelled()->withCount('customerBookings');请参阅此处接受的答案)。

但是:这不起作用。我想,这是因为一个预订属于一个客户,而一个客户有许多预订。

这是类 Booking 的 hasManyThrough 关系

public function customerBookings()
{
    // return the bookings of this booking's customer
    return $this->hasManyThrough(Booking::class, Customer::class);
}
Run Code Online (Sandbox Code Playgroud)

这是 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());
}
Run Code Online (Sandbox Code Playgroud)

报告错误

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)
Run Code Online (Sandbox Code Playgroud)

没有惊喜。没有这样的专栏customer.booking_id

问题

在这种情况下,预期的行为是否可能?如果是这样,我将如何急切加载预订客户的预订总数?

Jon*_*eir 8

尝试这个:

public function customer() {
    return $this->belongsTo(Customer::class)->withCount('bookings');
}

Booking::whereNotCancelled()->with('customer')->get();
Run Code Online (Sandbox Code Playgroud)