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

Selamlar, kendim boş vakitlerimde uğraştığım bir proje var. Burda herhangi bir takım içindeki kararların daha adil alınmasını sağlamaya çalıştım. Bu ne demek ?

Bir takım düşünelim. Bu takım ilk kurulduktan sonra güç dağılımı için oylama başlatılır. Her üye kendisi hariç, diğer üyelere toplamda 10.000 puan dağıtması gerekir. Her üye diğer üyelere puanları dağıttıktan sonra, üyeler güç puanına sahip olmuş olur. Bu güç puanları başlatılan diğer tipteki oylamalarda(çoklu seçenek oylaması, evet/hayır oylaması) kullandığı oyun değerini belirler. Güç puanlarını hiçbir üye göremez(lider dahil). Güç dağılımı taze kalması için her ay yapılır. Bunun gibi özellikler ve şartlar var.

Bunu canlıya aldım ve teste çıkardım. Backend API olarak laravel, frontend olarak vue kullandım. Kod kalitesi, tasarım, kod kurgusunu elimden geldiğince dikkat etmeye çalıştım. Projeden ziyade code review yapıp eleştiri yapmanız benim faydama olacaktır.

Proje Link: http://voteam.net

Demo Hesap
E-mail: voteamdemo@gmail.com
Şifre: voteam

Repo: https://github.com/halilcn/voteam

    Siteyi inceleyemedim beyaz ekran cikiyor ama githubdaki videolardan gordugum kadariyla guzele benziyor. Emek verilmis ve kayda deger bir calisma. Sadece kullanim alani kisitli gibi, ancak gelistirilebilir bir proje.

    • hcan bunu yanıtladı.
    • hcan bunu beğendi.

      hcan Şimdiye kadar incelediğim en temiz projelerden biri. Elinize sağlık. Gördüğüm birkaç şey şunlar:

      Eğer kullanıcının giriş yaparak geldiğinden eminseniz $request->user()->id kullanın, emin değilseniz Auth::id() ya da $request->user()?->id. Yoksa Trying to get property... alırsınız.

      API için kullandığınız resource controller'lar için Route::resource() yerine Route::apiResource() kullanabilirsiniz. Bu otomatik olarak create ve edit yöntemlerini devre dışı bırakır. Api resource controller php artisan make:controller API/UserController --api şeklinde de oluşturuluyor.

      Controller yöntemlerinde dönüş tipine ihtiyacınız yok çünkü onlar direkt tarayıcıya gönderilir. Eğer içeride siz bir controller'ı düz sınıf gibi kullanıp içinden bir yöntem çağırırsanız bu zaten yanlış kullanım demektir. Ayrıca object şeklinde bir dönüş tipi hatanın önüne geçmez, daha spesifik dönüş tipleri belirtmeniz lazım, :User gibi.

      return Exception::forgotPasswordException(); şeklinde return yapmanıza gerek yok, Exception::forgotPasswordException(); demeniz yeterli ki aslında throw new ForgotPasswordException() demeniz de yeterli. App\Exceptions\Exception sınıfını açıkçası gereksiz gördüm ve içindeki string ile namespace oluşturma pek sevdiğim bir yol değil.

      $user = User::where('email', $request->input('email'))->first(); yerine $user = User::firstWhere(['email' => $request->input('email')]); de kullanılabilir. Sadece bilgi amaçlı yazıyorum.

      $FINISHED_VOTE_LIMIT = 12; gibi direkt yöntem içinde tanımlamalar yerine sınıf özelliği olarak tanımlama yaparsanız diğer yöntemlerde de değere ulaşabilirsiniz. Değişmeyecek bir değer ise constant olarak tanımlayın.

      ->first()->member->id; gibi kullanımlar tehlikeli. Kayıt yoksa Trying to get property... alırsınız. Ya kaydın mutlaka olduğundan emin olun ya da null dönüşe izin veriyorsanız ->first()?->member?->id; kullanın.

      != yerine !==, == yerine === kullanın, tiplerden emin olun.

      Observer içinde Job dispatch yapmışsınız. Ben bunu doğru bulmuyorum çünkü event içindeki işlemlerin gerçekleşip de Job'ların ateşlenmesini istemediğiniz durumlar olabilir (örneğin bir artisan komutu içinde yapılan işlemler gibi). Bu durumda event dispatcher'ı da iptal edemezsiniz çünkü bu sefer tüm event içeriğini iptal etmiş olursunuz. Bu sıkıntının kaynağı bir yönteme birden fazla görev atamanız. Job ya da Event'ları sadece istediğiniz yerde anlık kullanın ve/veya listener yazın. Yöntemlere alakasız görevler yüklemeyin, sade olsunlar.

      Yöntem isimleriniz güzel, parametre tipleri ve dönüş tipleriniz de var ama aynısı PhpDoc ile de yazmışsınız. Eğer API dokümantasyonu çıkarmayacaksanız gereksiz PhpDoc kullanımlarından kaçının, kod zaten ne yaptığını anlatıyor.

      Bazı modellerde accessor tanımlarken eager loading kullanmadan sorgu yapmışsınız. Buralarda dikkatli olmanız lazım, eğer accessor bir iterasyon içinde kullanılırsa n+1 problemine sebep olur. Ör: Vote::getVotedPercentageAttribute() içindeki $this->votedUsers()->count();. Burada şöyle bir durumda var, eager loading kullanırken de bu sefer tüm votedUsers ilişkisini yükler, arada dengeli bir yol bulmanız gerekebilir.

      Accessor tanımarken geri dönüş tipine gerek yok çünkü hiç devreye girmiyor. getVotedPercentageAttribute():int değişsiniz mesela, burada dönüş tipi gereksiz.

      Model içindeki scope'lar daima Eloquent\Builder dönmeli. Siz normal yöntem gibi kullanıp bool vs döndürmüşsünüz. Ör: Vote::scopeHasUserVoted(). Bu, bir özelliğin suistimal edilmesi demek. hasUserVoted() şeklinde normal yöntem kullanın.

        mgsmus Vakit ayırdığınız için teşekkür ederim.

        Kuaza Sanırım anlık problem oldu. Kontrol ettim bir sorun yok gibi gözüküyor

        mgsmus $user = User::firstWhere(['email' => $request->input('email')]);
        Bu kullanimi cok sevdim. Incelemenizde cok iyi olmus hocam ellerinize saglik.

        mgsmus Şimdiye kadar incelediğim en temiz projelerden biri. Elinize sağlık.

        Kesinlikle öyle benim için de.
        Sevgili @mgsmus gerekenleri söylemiş.

        $INVITATION_URL

        API dizin ismi PSR açısından uygun değil, Api şeklinde olması daha uygun olacaktır.

        gibi kullanımlarınızın özel bir nedeni var mı?

        • hcan bunu yanıtladı.
          • Hhcan

              Seviye 56
            • Düzenlendi

            sineld Sanırım $INVITATION_URL gibi kullanımlarınızın özel bir nedeni var mı? şeklinde sordunuz.
            Genelde tanımlamaları en üstte yapıp gerekli yerlerde kullanmaya çalıştım. Burada tek bir noktada kullanılıyor ama kod okurken daha temiz gözüküyor. Dahar rahat okunabiliyor. O sebeple kullandım.

            10 gün sonra

            mgsmus firstWhere(['email' => $request->input('email')])

            firstWhere alanina birden fazla deger ekleyebiliyor muyuz ? Ornek:

            firstWhere(['email' => "email", "kullanici_adi"=>"kullanici"])

              Kuaza Evet. firstWhere sadece where(...)->first() için bir kısaltma aslında:

              public function firstWhere($column, $operator = null, $value = null, $boolean = 'and')
              {
                  return $this->where(...func_get_args())->first();
              }

              Bu durumda where ile tek seferde ne yapabiliyorsanız aynısını firstWhere için de yapabilirsiniz demektir:

              User::firstWhere('email', $email);
              
              User::firstWhere('created_at','<', now());
              
              User::firstWhere([
                  ['role', '=', 'customer']
                  ['balance', '>', 0],
              ]);
              
              User::firstWhere([
                  ['balance', '>', 0],
                  ['role', '=', 'admin']
              ], 'or');

              ama birden fazla değer için kullanmak okunabilirliği azalttığı için ilk iki verdiğim örnek dışındaki durumlarda kullanılmasını tavsiye etmem.