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

Dikkat : Tamamen beyin fırtınası yapalım diye sorulmuş bir soru.

Merhaba, şimdi diyelim ki bir e-ticaret sitesi geliştiriyoruz .

Kategori/t-shirt şeklinde bir linkimiz var ve bu link ile bu kategoriye ait ürünler listeleniyor.

Aynı şekilde bazı filitreler var ve bu filitrelere göre ajax kullanılarak farklı bir sayfada ürünler filitrelenip js ile güncelleniyor.

Aynı filitreler sayfa ilk açıldığında da çalışabilecek şekilde hem kategori controller'da hem ajax controller'da yazılmış olması gerekiyor. Bu da aynı kodu iki yerde yazmamıza neden oluyor.

Merak ettiğim konu aklınızda bu sorunu çözmek için bir pattern var mı? Benim aklıma bir builder class oluşturup parametre olarak da filtreleri verip sonucu almak ve bu class'ı tüm sorgu çalışan yerlerde kullanmak var böylelikle bir filtre eklememiz gerektiğinde tek bir yerden düzenlemiş olacağız.

Sonuçta bir sorgu çalıştırırken model çağırmak yerine bu builder class'ı çalıştırmış olucaz.

Daha temiz bir yaklaşım var mı aklınızda.

Uygulama SPA değil bu arada back-and de render oluyor sadece filtrelerde sonuçları güncellemek için ajax kullanılıyor.

  • mgsmus bunu yanıtladı.
  • gokhancelebi

    gokhancelebi Benim aklıma bir builder class oluşturup parametre olarak da filtreleri verip sonucu almak ve bu class’ı tüm sorgu çalışan yerlerde kullanmak var böylelikle bir filtre eklememiz gerektiğinde tek bir yerden düzenlemiş olacağız.

    Bu dediğiniz mantıklı ve ben kullanıyorum. Filtreleme için kullandığım ve tavsiye ettiğim paket şu:
    https://github.com/spatie/laravel-query-builder

    Yalnız ben bu paketi dokümanlarında belirtildiği gibi değil de tam da sizin dediğiniz gibi her yerde kullanılabilecek şekilde kullanıyorum. Mesela paketin örnek kullanımı normalde şu şekilde:

    $users = QueryBuilder::for(User::class)
        ->allowedFilters('name')
        ->allowedSorts('created_at')
        ->with('products')
        ->simplePaginate();

    Ben ise şöyle kullanıyorum:

    app/Queries/UsersQuery.php:

    namespace App\Queries;
    
    use Illuminate\Http\Request;
    use Spatie\QueryBuilder\QueryBuilder;
    
    class UsersQuery extends QueryBuilder
    {
        public function __construct(?Request $request = null)
        {
            $builder = User::query();
    
            parent::__construct($builder, $request);
    
            $this
                ->allowedFilters([
                    'name'
                ])
                 ->allowedSorts([
                    'created_at'
                ]);
        }
    }

    Bu şekilde yapınca örneğin herhangi bir controller ya da bir sınıf içinde aynen kullanabiliyorum. Sınıf Builder döndüğü için de istediğim şekilde ekleme yapıp çekiyorum.

    public function index(Request $request)
    {
        $users = new UsersQuery($request)
            ->with('products')
            ->simplePaginate();
    
        return view('users.index', compact('users'));
    }

    Atılan istek ise

    GET /users?filter[name]=Mustafa&sort=-created_at

    Bu şuna denk gelmiş oluyor:

    $users = User::with('products')
        ->where('name', 'like', '%Mustafa%')
        ->orderBy('created_at', 'desc')
        ->simplePaginate();

    Paketi kullanın demiyorum (ama şiddetle tavsiye ediyorum), aynı mantıkla kendi sınıfınızı kurabilirsiniz.

    • mgsmus

      Seviye 1383
    • Düzenlendi
    • En İyi Yanıtcoder2 tarafından

    gokhancelebi

    gokhancelebi Benim aklıma bir builder class oluşturup parametre olarak da filtreleri verip sonucu almak ve bu class’ı tüm sorgu çalışan yerlerde kullanmak var böylelikle bir filtre eklememiz gerektiğinde tek bir yerden düzenlemiş olacağız.

    Bu dediğiniz mantıklı ve ben kullanıyorum. Filtreleme için kullandığım ve tavsiye ettiğim paket şu:
    https://github.com/spatie/laravel-query-builder

    Yalnız ben bu paketi dokümanlarında belirtildiği gibi değil de tam da sizin dediğiniz gibi her yerde kullanılabilecek şekilde kullanıyorum. Mesela paketin örnek kullanımı normalde şu şekilde:

    $users = QueryBuilder::for(User::class)
        ->allowedFilters('name')
        ->allowedSorts('created_at')
        ->with('products')
        ->simplePaginate();

    Ben ise şöyle kullanıyorum:

    app/Queries/UsersQuery.php:

    namespace App\Queries;
    
    use Illuminate\Http\Request;
    use Spatie\QueryBuilder\QueryBuilder;
    
    class UsersQuery extends QueryBuilder
    {
        public function __construct(?Request $request = null)
        {
            $builder = User::query();
    
            parent::__construct($builder, $request);
    
            $this
                ->allowedFilters([
                    'name'
                ])
                 ->allowedSorts([
                    'created_at'
                ]);
        }
    }

    Bu şekilde yapınca örneğin herhangi bir controller ya da bir sınıf içinde aynen kullanabiliyorum. Sınıf Builder döndüğü için de istediğim şekilde ekleme yapıp çekiyorum.

    public function index(Request $request)
    {
        $users = new UsersQuery($request)
            ->with('products')
            ->simplePaginate();
    
        return view('users.index', compact('users'));
    }

    Atılan istek ise

    GET /users?filter[name]=Mustafa&sort=-created_at

    Bu şuna denk gelmiş oluyor:

    $users = User::with('products')
        ->where('name', 'like', '%Mustafa%')
        ->orderBy('created_at', 'desc')
        ->simplePaginate();

    Paketi kullanın demiyorum (ama şiddetle tavsiye ediyorum), aynı mantıkla kendi sınıfınızı kurabilirsiniz.

      mgsmus Çok güzel anlatmışsınız valla cevabımı aldım. Ben de request'i parametre olarak verebileceğim bir class düşünmüştüm.