Laravel’de Veritabanı Çeşitlilik İlişkileri (Polymorphic Relations) İşlemleri

tarafından
203
Laravel’de Veritabanı Çeşitlilik İlişkileri (Polymorphic Relations) İşlemleri
Güzel Hosting

Veritabanı ilişkileri denildiğinde o kadar çok şey gelir ki aklımıza biz bile bazen işin içinden çıkamayabiliriz. Şimdi bu geldiğimiz sorulara cevap bulabilmemize daha kolaylıklar tanıyacak veritabanı ilişkilerinde Polymorphic ilişkilere geçiyoruz. Aslında kelime anlamında biyoloji tabanlı bir kelime Türkçe’ye çevirdiğimizde çeşitlilik olarak adlandırabiliriz diye düşünüyorum. Diğer ilişkilere oranla daha karmaşık gelebileceği gibi diğer ilişkileri anlattığım yazıda anlattıklarımı çok iyi anlamış olmanız gerekmektedir. Gelin şimdi Polymorphic ilişkilerden bahsedelim.

One To Many Polymorphic Relations

Bu diğer yazımızda anlattığımız bire çok ilişkiden biraz daha bağımsız bir yapı bulunuyor. Anlatmam gerekirse bir tablo’yu ihtiyaçlarımız dahilinde ayarlayarak ilerde hiç bir değişiklik yapmadan ekleme yaptığımızda işleyişi bozulmadan devam edebilecek bir yapıdır. Örneklerle anlatırsak bir beğeni sistemimiz olsun ve bu beğenileri tuttuğumuz bir tablomuz olsun, bu tabloyu ilerde olabilecek yeni eklemelerde hiç bir değişiklik yapmadan yeni sistemle uyumlu olması gerekiyor bunu Polymorphic ilişkilerde çok basit bir şekilde yapabileceğiz. Gelelim yapacağımız işlemlere bir makale tablomuz olsun ve bu makalelere yapılan yorumlar olsun birde harici olarak bu iki tablonun beğenilerini kayıt ettiğimiz bir tablo olsun.
Yukarıda verdiğim ilişki ile yeni bir likes adında bir tablo oluşturma içerisindeyiz bu tablo kolonları ise; likeable_id ve likeable_type adında iki kolon oluşturuyoruz, likeable_id kolonuna örneğin bu bir makaleye ait beğeni ise hangi makalenin beğenisi olduğunu belirteceğiz yani benzersiz bir id girişi yapacağız, likeable_type kısmında ise bunun bir makaleye ait mi yoksa bir yoruma ait yoksa ilerde eklenecek yeni bir beğeni sistemine mi ait olacak bunu belirteceğiz bunu belirtirken direk olarak modelin tam adının girilmesi gerekmektedir (Örn. App\Post). Eğer mantığını anlatabildiysem gelelim kod yapılarına.
Likes modeline alt kısımdaki kodu ekleyelim.

    public function likeable()
    {
        return $this->morphTo();
    }

Üst kısımdaki kod’da bu beğeni neye ait birine ait birine ait ise bu biri kim ile bu veriye ulaşıyoruz. Bunu sistem likeable_type kolonuna yaptığınız girişe bakarak yapmaktadır.
Şimdi Gelelim Post modelimize yani makalelerimizi kontrol ettiğimiz modele, bunda ise ilgili makalenin beğenilerine ulaşıyoruz.

    public function likes()
    {
        return $this->morphMany('App\Like', 'likeable');
        //likeable kısmını tabloda belirttiğimiz kısımdır tablo değiştirtirsek burada da değiştirilmesi gerekmektedir. Sistem sonuna otomatik _id ve _type girişini yapmaktadır.
    }

Şimdi gelelim Comment yani yorumları kontrol ettiğimiz modele bunda ise ilgili yorumunu beğenilerine ulaşıyoruz.

    public function likes()
    {
        return $this->morphMany('App\Like', 'likeable');
        //likeable kısmını tabloda belirttiğimiz kısımdır tablo değiştirtirsek burada da değiştirilmesi gerekmektedir. Sistem sonuna otomatik _id ve _type girişini yapmaktadır.
    }

Bir örnekle ulaşımını anlatırsak alt kısımdaki kod’a başvurabiliriz.

$post = App\Post::find(1);
foreach ($post->likes as $like) {
    //
}

Dönen veriye dd() ile kontrol ederseniz, dönen veri collection veridir yani bunu ->likeable_type olarak gösteremeyiz. Bunun için bir foreach döngüsü içerisinde kontrol ediyoruz.

Many To Many Polymorphic Relations

Bu anlatacağımız ilişkide ise yine tamamen üst kısımdaki ilişkiye benzer bir ilişki kuracağız bu örneğimizdeki işlem ise oluşturduğumuz bir yazıda, yazıya verdiğimiz etiketlerin aynı anda bu yazıya ekleyeceğimiz videolara’da eklenmesini istiyoruz. Yani daha açıklayıcı olursak bir etiket hem bir yazıya ait olabilir, hemde bir video’ya ait olabilir veya birden fazla yazı veya birden fazla video bu tag’a ait olabilir. Bu işlem için Relationships’te anlatmış olduğum pivot mantığını burada kullanacağız. Öncelikle oluşturacağımız tabloları belirtelim. Post ve video tablolarının oluşturulduğunu varsayalım. Geriye iki tablo kalıyor bunlardan biri tags tablosu burada ekleyeceğimiz tagları yazıyoruz. Kolonlar sadece id,name olacak şekilde ayarlıyoruz. Diğer tablomuz ise pivot olan taggables tablosu bu kısımda dikkat edilmesi gereken nokta sonuna eklediğimiz “s” takısını daha sonra bir müdahale sonucu değiştirilmiyor olmasıdır. Yani biz bu tabloya taglar adını verir isek Many To Many Polymorphic ilişkide sonuna “s” takısını otomatik ekleyecek ve yapı çalışmaz hale gelecektir. Bunun için bu gibi durumlarda tablo adını taglars verilmesi gerekmektedir. Bu tablomuzda ise kolonlarımız tag_id,taggable_id ve taggable_type ‘dir. Burada tag_id tags tablosuna eklediğimiz tablosunun id’sidir. taggable_id ise taggable_type kolonunda belirttiğimiz modelin tablosundaki benzersiz id’dir. Veritabanlarını oluşturulması sırasında pivot tablo için harici bir model oluşturulması gerekmemektedir.
Şimdi ise Post modeline gelerek ilgili ilişki kod’unu yazıyoruz. Aynı kod’u video modeline eklediğinizde ise yine çalışacaktır. Bu şekilde ne oldu derseniz bir tag modülü oluşturarak tüm projenin hizmetine sunmuş olacağız. İlerleyen günlerde sadece Tag model’ini güncelleyerek mesela resim sistemine de tag eklemeyi çok basit bir şekilde getirebiliriz.

    public function tags()
    {
        return $this->morphToMany('App\Tag', 'taggable');
        // Üste belirttiğim gibi taggable tablo ismini belirtiyoruz, laravel ise sonuna "s" takısını otomatik ekliyor.
    }

Bu işlemi tersten yapıldığını düşünürsek yani 1 id’ye sahip tag hangi post veya videoya ait bunun tespitini yapabilmek için ilgili kodumuzu Tag Modelimiz içerisine yazıyoruz.

    public function posts()
    {
        return $this->morphedByMany('App\Post', 'taggable');
    }
    /**
     * Bu şekilde örneklerle tag sistemi geliştirilebilir.
     */
    public function videos()
    {
        return $this->morphedByMany('App\Video', 'taggable');
    }

Üst kısımdaki eklemeleri yaptığımıza göre bunu görüntüleme ve kontrol ise alt kısımdaki kod’u kullanabiliriz.
Post’ların Taglarına ulaşabilmek için kodumuz;

$post = App\Post::find(1);
foreach ($post->tags as $tag) {
    //
}

1 Id’ye sahip tag’ın hangi videolara ait olduğunu kontrol edelim.

$tag = App\Tag::find(1);
foreach ($tag->videos as $video) {
    //
}

İlişkilerde Query Builder Methodları

User::has('post')->get(); //Sadece Yazısı olan kullanıcıları getir.
User::has('post','>',3)->get(); //3'den fazla yazısı olan kullanıcıları getir.
User::withCount(['post','product'])->get(); //Kullanıcıların yazı ve ürün sayılarını getirir.

Daha ayrıntılı bilgi için laravel dökümantasyonunu inceleyebilirsiniz.
Yararlı olabildiysem ne mutlu, Hatam var ise bildirilirse düzeltebilirim.