Saya telah menemukan konsep dan makna di balik metode ini menjadi sedikit membingungkan, apakah mungkin bagi seseorang untuk menjelaskan kepada saya apa perbedaan antara has
dan with
dalam konteks contoh (jika mungkin)?
Saya telah menemukan konsep dan makna di balik metode ini menjadi sedikit membingungkan, apakah mungkin bagi seseorang untuk menjelaskan kepada saya apa perbedaan antara has
dan with
dalam konteks contoh (jika mungkin)?
Jawaban:
with()
untuk pemuatan yang cepat . Itu pada dasarnya berarti, di sepanjang model utama, Laravel akan melakukan preload hubungan yang Anda tentukan. Ini sangat membantu jika Anda memiliki koleksi model dan Anda ingin memuat relasi untuk semuanya. Karena dengan pemuatan yang cepat Anda hanya menjalankan satu permintaan DB tambahan alih-alih satu untuk setiap model dalam koleksi.
Contoh:
User > hasMany > Post
$users = User::with('posts')->get();
foreach($users as $user){
$users->posts; // posts is already loaded and no additional DB query is run
}
has()
adalah menyaring model pemilihan berdasarkan suatu hubungan. Jadi itu bertindak sangat mirip dengan kondisi WHERE normal. Jika Anda hanya menggunakan has('relation')
itu berarti Anda hanya ingin mendapatkan model yang memiliki setidaknya satu model terkait dalam hubungan ini.
Contoh:
User > hasMany > Post
$users = User::has('posts')->get();
// only users that have at least one post are contained in the collection
whereHas()
bekerja pada dasarnya sama seperti has()
tetapi memungkinkan Anda untuk menentukan filter tambahan untuk model terkait untuk diperiksa.
Contoh:
User > hasMany > Post
$users = User::whereHas('posts', function($q){
$q->where('created_at', '>=', '2015-01-01 00:00:00');
})->get();
// only users that have posts from 2015 on forward are returned
whereHas
pada relasi pengguna saat meminta posting.
whereHas
menggunakan use Illuminate\Database\Eloquent\Builder;
yang kemudian dengan function(Builder $query)
. Sebagian besar contoh yang saya lihat, gunakan titik Builder
, cukup masukkan $ query, yang merupakan cara yang benar?
Dokumen sudah menjelaskan penggunaannya. Jadi saya menggunakan SQL untuk menjelaskan metode ini
Anggap ada yang Order (orders)
punya banyak OrderItem (order_items)
.
Dan Anda sudah membangun hubungan di antara mereka.
// App\Models\Order:
public function orderItems() {
return $this->hasMany('App\Models\OrderItem', 'order_id', 'id');
}
Ketiga metode ini didasarkan pada suatu hubungan .
Hasil: with()
mengembalikan objek model dan hasil terkait.
Keuntungan: Ini adalah bersemangat-loading yang dapat mencegah N + 1 masalah .
Saat Anda menggunakan Eloquent Builder berikut:
Order::with('orderItems')->get();
Laravel mengubah kode ini menjadi hanya dua SQL :
// get all orders:
SELECT * FROM orders;
// get the order_items based on the orders' id above
SELECT * FROM order_items WHERE order_items.order_id IN (1,2,3,4...);
Dan kemudian laravel menggabungkan hasil dari SQL kedua sebagai berbeda dari hasil SQL pertama dengan kunci asing . Akhirnya mengembalikan hasil pengumpulan.
Jadi, jika Anda memilih kolom tanpa foreign_key di penutupan, hasil hubungan akan kosong:
Order::with(['orderItems' => function($query) {
// $query->sum('quantity');
$query->select('quantity'); // without `order_id`
}
])->get();
#=> result:
[{ id: 1,
code: '00001',
orderItems: [], // <== is empty
},{
id: 2,
code: '00002',
orderItems: [], // <== is empty
}...
}]
Has
akan mengembalikan objek model yang hubungannya tidak kosong .
Order::has('orderItems')->get();
Laravel mengubah kode ini menjadi satu SQL :
select * from `orders` where exists (
select * from `order_items` where `order`.`id` = `order_item`.`order_id`
)
whereHas
dan orWhereHas
metode untuk menempatkan where
kondisi pada has
kueri Anda . Metode ini memungkinkan Anda untuk menambahkan batasan khusus ke batasan hubungan .
Order::whereHas('orderItems', function($query) {
$query->where('status', 1);
})->get();
Laravel mengubah kode ini menjadi satu SQL :
select * from `orders` where exists (
select *
from `order_items`
where `orders`.`id` = `order_items`.`order_id` and `status` = 1
)
with('relation')
akan menyertakan data tabel terkait dalam koleksi yang dikembalikan,has('relation')
dan tidakwhereHas('relation')
akan menyertakan data tabel terkait. Jadi, Anda mungkin perlu untuk memanggil kedua serta atau .with('relation')
has()
whereHas()