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

Herkese öncelikle merhabalar laravel'de bir menüm var ve ben bunun altına alt kategorileri getirmek istiyorum bunu nasıl yapabilirim sorgu yapısını nasıl oluşturmalıyım

Merhaba,

Forumda bununla ilgili birçok başlık var, arama yaptınız mı?

    Forumda arama yaparsanız bu konunun tartışıldığı birçok başlık var.

    Paket kullanmak isterseniz bu paketi kullanabilirsiniz;
    https://github.com/lazychaser/laravel-nestedset

    Category Migrate:
    id - title - slug - parent_id
    Category Model:


    public function subCategories() {
        return $this->hasMany("App\Categroy", "id", "parent_id");
    }

    Sorgunuz;

    $categories = Category::where("parent_id", null)->with("subCategories")->get();

    Bu şekilde alt kategoriler ile beraber alabilirsiniz.
    Yazım hataları olabilir, kontrol etmedim. Varsa düzenlersiniz.

      coder2

      bu cok sıkıntılı bir query,kullanmamakta fayda var.Ucu açık bir döngüye sokar bu databasei..
      Talep edildiğinde her bir objenin alt listesini açmanız gerekiyor.

        sineld
        Forumdan bilgi alacağım, ulaşmaya çalışacağım teşekkür ederim

        deathisonitsway

        Hocam dün gece biraz düşündüm fakat neden sıkıntılı bir query olduğuna dair kafamda birşeyler oluşmadı.

        Rica etsem biraz daha detaylı anlatır mısınız ?

        Genelde yazdığım projelerde bu şekilde kullanıyorum, dediğiniz gibi hatalı bir kullanım ise doğrusunu öğrenip onu kullanmak benim için önemli.

          Nesini anlayamadın çok basit coder2 ... eloquent dediğin şey o ilişkiyi alıp sorgu atıyor.Nerde obje gorse alt ilişkisini arar.Sorgu yapar ve objeyle birleştirir.
          her bir resultset objesi için aynı sorguyu bir daha çalıştırıyor.20 tane objen olsun ve bu objeler bir alt ilişkiye sahip olsun o ilişkilerde kendi icinde bir alt ilişkiye sahip olsun..ağac mantıgında dusun..istediğim kadar ben alt ilişki yaratabilirim.Böyle dusundugunde sonu gelene kadar sorgu demektir.Database loadın tavan yapar..Hic bir endpoint bu sorguyu calıstırmaz.Sahibinden.com da calıstırmaz gittigidiyor da claıstırmaz..Talep edildiginde id bazlı tek alt ilişki calıstırılır..Boyle bir query ilk baslarda sana cok avantajlı gorunebilir ama..sistemin buyudukce bu sorgu başına bela açar..

            deathisonitsway
            Hocam navbar da göstereceğim kategorilerde nasıl bir yöntem kullanacağım o zaman ?

            Tüm kategorileri çekip collection ile parçalayarak gösteriyorum bazen, bazende bu şekilde belirttiğim gibi relation ile alıyorum.

            Vay arkadaş 🙂 inanılmazsınız.Collection resultseti filtrelemekten başka bir halta yaramaz.
            Bir anda onbinlerce query yapabileceğinizi hayal edemiyorsunuz.Bu recursive queryi ben kullanmam.
            Hangi ürün talep ediliyorsa onun idsini alırım parent_id si neyse onları getiririm..Oyle recursive query kimse yapmıyor.
            Yapmamalıda..yani bu kendini yineleyen modelleme çeşidini unutmanız gerekiyor.
            Ha dediğim gibi yapılır mı yapılır..Döndürür durursun eloquenti..Ama emin ol kolay yapmıyor bunu..yeni bir query atıyor.O obje ile ilişkili ne varsa aynı modeli tekrar tekrar dondurcek..Valla o kadar paranız varsa yapın.Birşey demem..Timeouta dusmezse alırsın resultseti..Bir şekilde çalışır mı çalışır..ama dönene kadar bekler durursun gün gelir.

              deathisonitsway
              Hocam sanırım tam olarak anlatamıyorum kendimi.
              Bir website de navbar da kategorileri (Alt kategoriler ile beraber) gösterirken/listelerken ne şekilde yapıyorsunuz siz ?

              Neden onbinlerce query yapacak onu da anlamış değilim, zaten kullanıcı siteye girince bir defaya mahsus kategorilerle ilgili sorgu yapıyor sonra cache den okuyor.

              @coder2
              Hocam trafiğiniz düşükse çok problem değil. Ama yüksekse 1 sorguda 10 tane sorgu ekstra çalışır ama bu 5.000 kişi de 50.000 sorgu eder. Yani trafik artınca etkisi görülür ancak.

              Bunu şöyle yaparız biz bu tür yüksek trafikli sitelerde.
              Bir menümüz olsun.

              1. Arabalar
                • Audi
                  • a3
                  • a5
                  • a7
                    • dizel
                    • benzinli
                    • tüplü
                • Mercedes
                  • a180
                  • a200

              2.Kamyonlar
              .....

              Böyle gidiyor diyelim. Bu iç içe menüleri tek seferde çekerseniz olmaz. İlk önce 1.level menüleri çekersiniz. Adam arabalara tıklayınca Arabalar ın ID'si 1 ya, gidip arabaların alt menülerini 1 id ile çekersiniz Audi ve Mercedes gelir. Sonra adam Audi ye tıklarsa gidip audi nin id si ile a3, a5, a7 yi çekersiniz. Sonra a7 ye tıklayınca onun id si ile dizel, benzinli, tüplü yü çekersiniz. Böyle böyle aşağı doğru inersiniz.

              Adamın kamyonlarla işi yok, mercedesle işi yok, a3 ve a5 le işi yok ama bunları her seferinde çekmiyorsunuz. Adım adım çekiyorsunuz. Hem anlık sorgu maliyetiniz hem total sorgu maliyetiniz minimuma iniyor.

              @deathisonitsway in söylemek istediği budur. 😀

              Hah adamım geldi beni kurtardı ya 🙂 @alihankoc valla oturup eager loadingin nasıl calıstıgını aksam frameworkun çekirdeğinden gösterecektim 🙂 ama gerek kalmadı..

              @coder2 dostum cache yapıyorsan kurtarırsın bir şekilde ama yolu bu değil tabi.Kendini sürekli tekrar eden bir queryden uzak tutmalısın.Demek istediğim o.Yani database de tuttuğun her bir veri için extra bir query yapacak modelin.Ve her bir modelin alt categoryleri için yapacaktır.Ne kadar alt ilişki varsa tümüyle extra query demek.Hatta olsun olmasın her bir alt query icin bile N+1 query yapacaktır modelin.Yüksek trafik alan siteler için asla yapılmayacak bir querydir bu.Ha diyorsan ben sorun yaşamıyorum yaşamamıssındır doğaldır.Yığ bakalım trafiği sitene..ve 10 binlerce alt alta kategorin olsun sisteminde..O menü geliyor mu gelmiyor mu görürsün 🙂 Ve herşeyi geçtim..Tek sefer de kullanamayacaksın bu kadar menuyu sayfaya dizmeye o yüzden query yaptığınla kalacaksın.

              Sahibinden coma bakarsan eğer sadece tek alt düzeyli ilişkiyi getiriyor.Talep edildikçe ilgili datanın yine tek bir alt ilişkisini getiriyor.Ha onlarda deli gibi bir cache mekanizması var o ayrı.

              Senin queryni sahibinden.com da asla calıstıramazsın.over load dan down olur sistem.

              6 gün sonra

              Konuyu belki hortlatmış gibi olacağım ama lazım olacak kişilere bir alternatif olsun diye yazacağım. iç içe sayısı sabit olamayan kategoriler için tek bir query ve ardından bir php fonksiyonu ile rahatça halledilebiliyor.
              örnek tablo bu şekilde olursa
              id|adi|parent
              1|ana başlık 1|null(veya 0)
              2|1. alt başlık|1
              3|2. alt başlık|1
              4|3. alt başlık|3
              5|ana başlık 2|null

              tablodaki kayıtların bu şekilde olduğunu varsayarsanız ve elde etmek istediğiniz sonuç;

              • ana başlık 1
                • 1. alt başlık
                • 2. alt başlık
                  • 3. alt başlık
              • ana başlık 2

              bu şekilde ise

              private function createTree (&$list, $parentId = null) {
                      $tree = array();
                      foreach ($list as $key => $eachNode) {
                          if ($eachNode['parent'] == $parentId) {
                              $eachNode['children'] = $this->createTree ($list,$eachNode['id']);
                              $tree[] = $eachNode;
                              unset($list[$key]);
                          }
                      }
                      return $tree;
                  }

              yukarıda belirttiğim fonksiyona $this->createTree($kayitlar) olarak çağırdığınızda size iç içe girmiş şekilde sonuç verecektir. Bu durumda her bir kayıt için alt kategori var mı yok mu diye kontrol etmektense tek bir sorguda sonuçları alıp ufak bir işlemle bunu sağlayabilirsiniz.

              geçtiğimiz günlerde lazım olmuştu buraya iliştirmiş olayım.

                @Ekrem hocam yukarda arkadaşlar bu şekilde tüm kategorileri çekmenin performans açısından doğru olmayan bir yol olduğunu söylüyorlar.
                Anladığım kadarıyla ana kategorileri çekip listeletin, eğer kullanıcı alt kategorileri açmak isterse bir sorgu daha atarak o kategoriye ait birinci seviye alt kategorileri çekin ..... şeklinde bir mantık kurmaktan bahsediyorlar.

                Notlarım arasına yazdım, bir sonraki projemde bu şekilde deneyeceğim.

                  coder2 Hocam 50-100 tane kaydı db den çekmek pek de performans kaybı sağlayacağını zannetmiyorum.

                  Burada 2 mantık vardır. Menü, Katagori/Sub Kategori vs. mantığında yukarıdaki kod iş görecektir.
                  Ama bir ürün filtreleme sayfasında seçilen özelliklere ait alt özellik filtreleme vs. mantığında yukarıdaki kod işe yaramaz.

                  Yani eğer amaç Menü/Alt Menü - Kategori/Alt Kategoriyse olsun en fazla 250 kayıt.
                  Örnek bir uygulamamda iç içe başlıkların olduğu toplamda 980 bin tane kaydın içerisinde belirli id ye göre çekip kiminde 3-5 kiminde ise 200 tane den fazla başlık çekip bu şekilde Tree oluşturuyorum hiç de sıkıntısını görmedim açıkçası.

                  13 gün sonra

                  Ekrem hocam bende laravel e yeni başladım kategori sistemini kullanmaya çalışıyorum. bu controller'ı yazdım ve blade kısmında çekmeye çalıştım ama beceremedim.Route da tanımlama yapmam gerekiyor galiba ama nasıl oldugunu bilmiyorum yardımcı olursanız çok sevinirim.

                    Ekrem hocam şimdi şöyle yaptım ama başka bir tablo olunca index e onu yollayamıyorum bu seferde
                    controller kısmı

                    public function getIndex()
                        {
                            $kategori = Categories::all();
                            return view('index', array('kategoriliste'=>$kategori));
                        }

                    model kısmı mesela burada iki tabloyuda çekiyim dedim olmadı

                    class Categories extends Model
                    {
                       protected  $table = "categories";
                       protected  $table2 = "sliders";
                    }

                    route kısmı tam burada gönderiyorum yine anasayfaya ama çakışıyor galiba yada yanlış yapıyorum hata veriyor.
                    Route::get('/','CategoriesController@getIndex');