通过预先加载消除重复查询

时间:2018-01-05 22:21:42

标签: php laravel eloquent lazy-loading eager-loading

我正在尝试在我的网站上消除不必要的查询,但我正在努力绕过Eager Loading和Lazy Loading。我网站上的所有用户都有列表,列表中有多个用户。它们通过表listing_users连接。每个商品都有一个"订单"与之相关联。这是用户模型:

用户模型:

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'));
}

我的刀片视图user.listings中出现问题,其中每个列表都有一个foreach循环,然后调用每个订单。我需要一种方法将列表传递给页面,并附上相关的订单。

  @foreach($listings as $listing)
    @if($listing->order()->status == 'completed')
      {{-- Display the listing details here --}}
    @endif
  @endforeach 

对于上述情况的任何建议将不胜感激!我确信有一个简单的Laravel解决方案,我可以忽视它。

1 个答案:

答案 0 :(得分:0)

试试这个:

列表模型:

public function order(){
  return $this->hasOne(Order::class); //without first()
}

<强> UserController中: 在这里,我们使用方法with('order')为查询检索的每个Order模型预先加载Listing模型。所以现在你的刀片不会是不必要的查询。

  

当访问Eloquent关系作为属性时,关系   数据是&#34;延迟加载&#34;。这意味着关系数据不是   实际加载,直到您第一次访问该属性。然而,雄辩   可以&#34;渴望加载&#34;查询父模型时的关系。

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,请将其与()一起用作查询构建器,并添加其他约束,例如whereorderBy等,最后添加{{1} }。 在这里,您可以了解我们从first()上方移除first()的原因。

hasOne