使用预加载消除重复查询
Eliminating Duplicate Queries with Eager Loading
我正在努力消除我网站上不必要的查询,但我正在努力思考急切加载和延迟加载。我网站上的所有用户都有列表,列表有多个用户。它们通过 table listing_users 连接。然后每个列表都有一个 "order" 与之相关联。这是用户模型:
用户模型:
public function listings(){
return $this->belongsToMany(Listing::class)->withPivot('role_id');
}
上市型号:
public function order(){
return $this->hasOne(Order::class)->first();
}
我当前的仪表板是通过在 UserController 中调用此 viewListings 加载的:
public function viewListings(){
$user = Auth::user();
$listings = $user->listings()->orderBy('created_at','desc')->get();
return view('user.listings', compact('listings'));
}
问题出现在我的 blade 视图 user.listings 中,我对每个列表都有一个 foreach 循环,然后也调用每个订单。我需要一种方法将列表及其相关订单传递到页面。
@foreach($listings as $listing)
@if($listing->order()->status == 'completed')
{{-- Display the listing details here --}}
@endif
@endforeach
如有任何针对上述情况的建议,将不胜感激!我确定有一个我忽略的简单 Laravel 解决方案。
试试这个:
上市型号:
public function order(){
return $this->hasOne(Order::class); //without first()
}
用户控制器:
在这里,我们使用方法 with('order')
为查询检索到的每个 Listing
模型预先加载 Order
模型。所以现在在你的blade不会有不必要的查询了。
When accessing Eloquent relationships as properties, the relationship
data is "lazy loaded". This means the relationship data is not
actually loaded until you first access the property. However, Eloquent
can "eager load" relationships at the time you query the parent model.
public function viewListings(){
$user = Auth::user();
$listings = $user->listings()->orderBy('created_at','desc')
->with('order')->get();//added with('order')
return view('user.listings', compact('listings'));
}
user.listings:
如果您需要检索您的模型,您应该使用 order
而不使用 ()
。因此,如果你想修改 order
然后将它与 ()
一起用作查询构建器,并添加进一步的约束,如 where
、orderBy
等,最后添加 first()
.
在这里您可以理解为什么我们从上面的 hasOne
中删除了 first()
。
@foreach($listings as $listing)
@if($listing->order->status == 'completed')
{{-- order instead of order() --}}
{{-- Display the listing details here --}}
@endif
@endforeach
我正在努力消除我网站上不必要的查询,但我正在努力思考急切加载和延迟加载。我网站上的所有用户都有列表,列表有多个用户。它们通过 table listing_users 连接。然后每个列表都有一个 "order" 与之相关联。这是用户模型:
用户模型:
public function listings(){
return $this->belongsToMany(Listing::class)->withPivot('role_id');
}
上市型号:
public function order(){
return $this->hasOne(Order::class)->first();
}
我当前的仪表板是通过在 UserController 中调用此 viewListings 加载的:
public function viewListings(){
$user = Auth::user();
$listings = $user->listings()->orderBy('created_at','desc')->get();
return view('user.listings', compact('listings'));
}
问题出现在我的 blade 视图 user.listings 中,我对每个列表都有一个 foreach 循环,然后也调用每个订单。我需要一种方法将列表及其相关订单传递到页面。
@foreach($listings as $listing)
@if($listing->order()->status == 'completed')
{{-- Display the listing details here --}}
@endif
@endforeach
如有任何针对上述情况的建议,将不胜感激!我确定有一个我忽略的简单 Laravel 解决方案。
试试这个:
上市型号:
public function order(){
return $this->hasOne(Order::class); //without first()
}
用户控制器:
在这里,我们使用方法 with('order')
为查询检索到的每个 Listing
模型预先加载 Order
模型。所以现在在你的blade不会有不必要的查询了。
When accessing Eloquent relationships as properties, the relationship data is "lazy loaded". This means the relationship data is not actually loaded until you first access the property. However, Eloquent can "eager load" relationships at the time you query the parent model.
public function viewListings(){
$user = Auth::user();
$listings = $user->listings()->orderBy('created_at','desc')
->with('order')->get();//added with('order')
return view('user.listings', compact('listings'));
}
user.listings:
如果您需要检索您的模型,您应该使用 order
而不使用 ()
。因此,如果你想修改 order
然后将它与 ()
一起用作查询构建器,并添加进一步的约束,如 where
、orderBy
等,最后添加 first()
.
在这里您可以理解为什么我们从上面的 hasOne
中删除了 first()
。
@foreach($listings as $listing)
@if($listing->order->status == 'completed')
{{-- order instead of order() --}}
{{-- Display the listing details here --}}
@endif
@endforeach