Sorguyu düz sql cümlesi olarak nasıl yazabileceğimizle başlarsak sonuca daha kolay ulaşabiliriz.
posts tablosu ile likes tablosunu uygun şekilde join ediyor, posts tablosundan tüm alanları, likes tablosundan post_id alanının sayısını toplam adı altında alıyor, toplamları likes tablosunun post_id alanına göre grupluyor, toplama göre çoktan aza sıralıyor ve ilk 5 satırı getirtiyoruz.
Veritabanı olarak mySQL kullanılıyorsa, sıkı kurallı bir ifade biçimi olmadığından düz sql cümlesi şöyle olabilecektir:
"SELECT posts.*, COUNT(likes.post_id) AS toplam FROM posts JOIN likes ON posts.id=likes.post_id GROUP BY likes.post_id ORDER BY toplam DESC LIMIT 0,5"
Zorlanılan yerde ham sql ya da direkt sorgu kullanmaktan çekinmek gerekmez. Bu itibarla, direkt sorgu kullanabiliriz:
$postlar = DB::select("SELECT posts.*, COUNT(likes.post_id) AS toplam FROM posts JOIN likes ON posts.id=likes.post_id GROUP BY likes.post_id ORDER BY toplam DESC LIMIT 0,5");
Bu durumda $postlar, PHP stdClass türünde nesnelerden oluşan bir dizi olacaktır.
Ama sonucu illa ki, Eloquent türünde bir nesne olarak döndürmek istiyorsak, Eloquent sorgulaması kullanabiliriz, yine de likes tablosunun gerçek olgusunu kullanmadığımız için (gerçek olguda count(..) diye bir alan yoktur), seçim kısmında ham sql kullanmamız gerekecektir. posts tablosunun model isminin Post olduğunu kabul ederek:
$postlar = Post::join('likes', 'posts.id', '=', 'likes.post_id')
->select(DB::raw('posts.*, count(likes.post_id) as toplam'))
->groupBy('likes.post_id')
->orderBy('toplam', 'desc')
->take(5)
->get();
Bu sefer $postlar, Eloquent Post modeli türünde nesnelerden oluşan bir koleksiyon olacaktır. Post modelinin orijinal alanlarına bir de toplam adında bir alan eklenmiş olacaktır.
stdClass dizisinde de Eloquent koleksiyonu gibi, her elemanın alanlarına sınıf nitelikleri şeklinde erişebiliriz. Örneğin:
foreach($postlar as $post)
{
echo 'Post Id: ', $post->id, ', Post Başlığı: ', $post->title, ', Beğeni Sayısı: ', $post->toplam, '<br>';
}