Laravel Türkiye Discord Kanalı Forumda kod paylaşılırken dikkat edilmesi gerekenler!Birlikte proje geliştirmek ister misiniz?

Selamlar,

Normal de ilişkisel bir tabloda nesneleri yukarıdan aşağı doğru hiyerarşik olarak rahat bir şekilde alabiliyoruz. Peki ya aşağıdan yukarı doğru almak istersek ? Yani node'un en alt elemanından başlayıp yukarı doğru parentları hiyerarşik olarak getirmek.

Aslında metod aşağıdaki örnekte sorunsuz bir şekilde çalışıyor ama kodu gördükten sonra neden konuyu açtığımı anlayacaksınız.

public function getParentCategoriesOfCategory(int $id): array
{

if ($id != 0) {

    $category = $this->category::find($id);
    
    array_push(self::$categories, $category->parentCategory);
    
    if (isset($category->parentCategory)) {
        $this->getParentCategoriesOfCategory($category->parentCategory->id);
    }
}

    return self::$categories;
}

Yukarıda gerçekleşen akış şu; id'yi alan metod, önce nesneyi sınıfın statik özellğine basıyor. Sonra eğer üst bir node varsa, tekrar metod çağrılıyor ve sınıfın statik özelliğine push etmeye devam ediyor.

Aslında eğer alt node'dan üste doğru değilde, üstten aşağı doğru bağlamları hiyerarşik almak isteseydik statik sınıf özelliği oluşturmadan yukarıdaki metoda benzer bir recursive metod yazıp sonucu kolayca alabilirdik. Ancak aşağıdan yukarı doğru hiyerarşiyi almak istemek statik özellik oluşturmaya zorluyor.

Benimde sorum tam burada devreye giriyor. Bu sorunu statik özellik veya yöntemler kullanmadan aşmanın bir yolunu bulabilir miyiz ? Denemelerim devam ediyor ama sizinde fikrinizi almak istedim.

    acncii Bu kullandığınız yöntem Adjacency List olarak geçer. Veri eklemesi kolaydır fakat okuması ise zordur. Bunun yerine Nested Set yöntemini araştırmanızı öneririm. Nested Set'de ise veri eklemesi zordur fakat okuması kolaydır, parent_id değil de küme mantığı ile çalışır:

    Her bir kaydın bir left (lft) ve bir de right (rgt) değer vardır. Bunlar eklenirken eklendikleri yere göre hesaplanırlar, tüm ağacın left right değerleri baştan hesaplanır ve değişir. Bu yüzden eklemesi zordur. Üstteki resimde eklenirken nasıl left right değerleri hesaplanmış onu gösteriyor. Elbette bunu kod ile ifade etmek kolay değil.

    Okuması ise kolaydır. Mesela A burada kök. A'nın tüm çocuklarını almak için:

    SELECT * FROM tree WHERE lft > 1 AND rgt < 16

    yapabilirsiniz. Burada aslında bir küme işlemi yapıyorsunuz. Sol ve sağ değeri 1 ile 16 arasındaki kayıtları getir diyorsunuz. Resme bakarsanız A dışındaki bütün kayıtların left değeri 1 den büyük; right değeri 16'dan küçük. Mesela leaf denen en alttaki alt kategorilere bakalım. Bunlar D,E,G ve H. Bunları almak istersek:

    SELECT * FROM tree WHERE lft = (rgt - 1)

    Resme tekrar bakarsanız eğer D,E,G ve H bu dediğime uyuyor. D'nin right değeri 4; left değeri 3, yani left daima right değerinden 1 eksik.

    Bunun gibi bir sürü konu var araştırmanız gereken. Hiyerarşik verinin veritabanında tutulması ve okunması ayrı bir alan diyebilirim.

    Şunları inceleyebilirsiniz:
    https://github.com/BlueM/Tree (PHP Adjacency List için kullandığım bir paket, gayet başarılı)
    https://github.com/lazychaser/laravel-nestedset (Laravel'de Nested Set için kullandığım bir paket, gayet başarılı)
    https://www.alberton.info/talks/show/id/1 (Güzel bir sunum)
    https://en.wikipedia.org/wiki/Nested_set_model (Genel bilgi)
    http://troels.arvin.dk/db/rdbms/links/#hierarchical (Konu ile ilgili bir çok link barındırıyor.)

    Kaynaklar çok sağlam mustafa teşekkür ederim. Veritabanlarını modellerken bu tarz metodolojilere göre kurgulamak çok önemli. Paketler işimizi kolaylaştırmış tekrar sağol.