代码之家  ›  专栏  ›  技术社区  ›  bdweix

通过即时加载消除重复查询

  •  2
  • bdweix  · 技术社区  · 7 年前

    我试图消除我的网站上不必要的查询,但我努力围绕着渴望加载和懒惰加载。我网站上的所有用户都有列表,列表中有多个用户。它们通过列出用户的表连接。每个列表都有一个与之相关联的“顺序”。以下是用户模型:

    用户模型:

    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 view用户中。清单中,我对每个清单都有一个foreach循环,然后调用每个订单。我需要一种方法来传递列表的页面,与他们的相关订单。

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

    如果您对上述情况有任何建议,我们将不胜感激!我确信我忽略了一个简单的拉拉维尔解决方案。

    1 回复  |  直到 7 年前
        1
  •  0
  •   yrv16    7 年前

    试试这个:

    上市模式:

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

    用户控制器: 这里我们使用方法 with('order') 用于快速加载 Order 每个的模型 Listing 通过查询检索的模型。所以现在在你的刀片上就不会有不必要的查询了。

    当将雄辩的关系作为属性访问时,关系 数据是“延迟加载的”。这意味着关系数据不是 直到您第一次访问该属性时才实际加载。然而,雄辩 可以在查询父模型时“即时加载”关系。

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

    使用者列表: 你应该使用 order 没有 () 如果需要检索模型。所以如果你想修改 顺序 然后将其用于 () 作为查询生成器,并添加其他约束,如 where , orderBy 等等,最后加上 first() . 在这里你可以理解为什么我们删除了 第一() 从…起 hasOne 在上面

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