Menghilangkan Kueri Duplikat dengan Pemuatan Bersemangat

Saya mencoba menghilangkan pertanyaan yang tidak perlu di situs saya, tetapi saya kesulitan memahami Eager Loading dan Lazy Loading. Semua pengguna di situs saya memiliki listingan, dan listingan memiliki banyak pengguna. Mereka terhubung melalui tabel listing_users. Setiap daftar kemudian memiliki satu "urutan" yang terkait dengannya. Berikut adalah model penggunanya:

Model Pengguna:

public function listings(){
   return $this->belongsToMany(Listing::class)->withPivot('role_id');
}

Model Daftar:

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

Dasbor saya saat ini dimuat dengan memanggil viewListings ini di UserController:

public function viewListings(){
  $user = Auth::user();
  $listings = $user->listings()->orderBy('created_at','desc')->get();
  return view('user.listings', compact('listings'));
}

Masalahnya terjadi pada tampilan blade saya user.listings di mana saya memiliki loop foreach untuk setiap daftar dan kemudian memanggil setiap pesanan juga. Saya memerlukan cara untuk meneruskan daftar ke halaman, dengan pesanan terkait.

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

Saran apa pun untuk situasi di atas akan sangat dihargai! Saya yakin ada solusi Laravel sederhana untuk ini yang saya abaikan.


person bdweix    schedule 05.01.2018    source sumber


Jawaban (1)


Coba ini:

Model Daftar:

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

UserController: Di sini kita menggunakan metode with('order') untuk memuat model Order dengan penuh semangat untuk setiap Listing model yang diambil berdasarkan kueri. Jadi sekarang di bilah Anda tidak akan ada pertanyaan yang tidak perlu.

Saat mengakses hubungan Eloquent sebagai properti, data hubungan "dimuat dengan lambat". Ini berarti data hubungan belum benar-benar dimuat hingga Anda mengakses properti tersebut untuk pertama kali. Namun, Eloquent dapat "bersemangat memuat" hubungan pada saat Anda menanyakan model induk.

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: Anda harus menggunakan order tanpa () jika Anda perlu mengambil model Anda. Jadi jika Anda ingin memodifikasi order maka gunakan dengan () sebagai pembuat kueri, dan tambahkan batasan lebih lanjut seperti where, orderBy dll. dan pada akhirnya tambahkan first(). Di sini Anda dapat memahami mengapa kami menghapus first() dari hasOne di atas.

@foreach($listings as $listing)
   @if($listing->order->status == 'completed')
    {{-- order instead of order() --}} 
     {{-- Display the listing details here --}}
   @endif
@endforeach 
person yrv16    schedule 05.01.2018
comment
Meskipun ini seharusnya berhasil, ini akan sangat membantu OP dan orang lain yang menelusuri untuk menjelaskan apa yang Anda lakukan dan mengapa hal ini menyelesaikan masalah. - person patricus; 06.01.2018