Teknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor Haberleri
Yazı Tipi BoyutlandırıcıAa
  • Anasayfa
  • Teknoloji
    • Siber Güvenlik
    • Yapay Zeka
    • Donanım
    • Bilim
  • Yazılım
  • Savunma & İstihbarat
  • Oyun
  • Yaşam
    • Finans
    • Sinema
    • Dünyadan Haberler
  • İş Birliği
Okuma: Bir Nullable Zaman Damgası, Dört Hesap Durumu: Laravel’de Kullanıcı Durumunu Türetmek
Paylaş
Yazı Tipi BoyutlandırıcıAa
Teknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor Haberleri
Ara
Bizi Takip Et
  • Hakkımızda
  • Gizlilik politikası
  • Tanıtım Yazısı ve Backlink Hizmeti
© 2026 Teknomers. All Rights Reserved.

Anasayfa » Bir Nullable Zaman Damgası, Dört Hesap Durumu: Laravel’de Kullanıcı Durumunu Türetmek

Yazılım

Bir Nullable Zaman Damgası, Dört Hesap Durumu: Laravel’de Kullanıcı Durumunu Türetmek

teknomers
Son güncelleme: 12 Haziran 2026 17:24
teknomers
Paylaş
Paylaş

Günlük işlerimden çoğu, kickoff – benim Laravel başlangıç kitim üzerinde kullanıcı yönetimi yenilenmesine harcandı. Açılır CRUD panelleri, toplu işlemler, izin ataması ve ele almak istediğim bölüm: hesap durumu. Aktif, askıya alınmış, doğrulanmamış, silinmiş.

İlginç kısım, özelliğin kendisi değil. Asıl önemli olan, altında yatan modelleme kararları. Bu dört durum aslında nerede yaşıyor?



Kısır döngü: bir status sütunu

Açık bir adım, users tablosuna bir status enum sütunu eklemektir. Birini askıya alırken suspended olarak ayarlayın, işini yeniden kurduğunuzda active ile geri getirin, e-posta doğrulanmasını beklerken unverified ayarlayın ve silindiğinde ise deleted olarak belirleyin.

Bu işliyor. Ta ki çalışmayana kadar. Artık bir status sütununuz ve bir email_verified_at sütununuz ve soft delete’ler için bir deleted_at sütununuz var – ve bu üçü çelişen gerçekleri kodluyor. Bir kullanıcıyı soft-delete yapıp status değerini değiştirmeyi unutursanız, artık veritabanınız hem active hem de silinmiş diye söylüyor. E-postayı doğrulayın ama durum güncellemesi isteği ortasında başarısız olursa? Drift. Kullanıcıyı değiştiren her yer, status‘u senkronize tutmayı hatırlamak zorunda. Bu bir özellik değil, bu bakım vergisidir.

İşaretler zaten mevcut. email_verified_at doğrulandı veya doğrulanmadı bilgisini verir. deleted_at (soft delete’lerden) kaldırıldı veya kaldırılmadığı bilgisini gösterir. Gerçekten yeni olan durum, suspended – yönetici tarafından kasten girişin engellendiğidir. Bu yüzden saklanmaya değer olan tek şey budur.



Ne saklarız: bir nullable timestamp

Schema::table('users', function (Blueprint $table) {
            $table->timestamp('suspended_at')->nullable()->after('email_verified_at');
        });
        

Bu, tüm migrasyondur. Bir boolean is_suspended değil – bir nullable timestamp. Null, askıya alınmadığı anlamına gelir; bir değer, askıya alındığı anlamına gelir ve ne zaman olduğunu söyler. Boolean, bu ikinci gerçeği kaybeder; timestamp, ekstra maliyet olmadan bunu tutar. email_verified_at ve deleted_at ile aynı içgüdü – Laravel modelleri “bu oldu mu ve ne zaman” bilgilerini her yerde nullable timestamp olarak saklar, bu yüzden framework’ün genel akışına uyuyoruz.

Model üzerindeki davranış küçülür:

public function isSuspended(): bool
        {
            return $this->suspended_at !== null;
        }

        public function suspend(): void
        {
            $this->forceFill(['suspended_at' => now()])->save();
        }

        public function unsuspend(): void
        {
            $this->forceFill(['suspended_at' => null])->save();
        }
        



Durum türetilmiştir, asla saklanmaz

Burada yol; status(), bir sütun okuma değil – sinyaller üzerinde, öncelik sırasına göre bir match biçimindedir:

public function status(): UserStatus
        {
            return match (true) {
                $this->trashed()                   => UserStatus::DELETED,
                $this->isSuspended()               => UserStatus::SUSPENDED,
                $this->email_verified_at === null  => UserStatus::UNVERIFIED,
                default                            => UserStatus::ACTIVE,
            };
        }
        

match (true), bir cond gibi okunur – koşulunun true olduğu ilk kısım kazanır, böylece öncelik sırası belirlenir. Silinmiş, askıya alınmış, doğrulanmamış, aktif sıralaması ile ilerler. Bir silinmiş ve askıya alınmış kullanıcı DELETED olarak değerlendirilir ki bu istenendir: en güçlü gerçek kazanır ve karar veren tek bir yer vardır. Drift yoktur, çünkü senkronize tutacak hiçbir şey yoktur – durum, diğer Laravel parçalarının zaten sizin için sürdüğü sütunlardan tazelenerek hesaplanır.

Sorgulama aynı muameleyi alır, böylece “aktif” bir liste sorgusunda olduğu gibi tekil modelde de aynı anlama gelir:

public function scopeActive(Builder $query): Builder
        {
            return $query->whereNull('suspended_at')->whereNotNull('email_verified_at');
        }

        public function scopeSuspended(Builder $query): Builder
        {
            return $query->whereNotNull();
        }
        



Enum kendi sunumunu taşır

UserStatus, bir string destekli enum’dur, ancak bir Contract uygulamakta ve label() / color() / description() yüzeyini sunan bir InteractsWithEnum trait’ini çekmektedir (benim traitify paketimden) :

enum UserStatus: string implements Contract
        {
            use InteractsWithEnum;

            case ACTIVE = ;
            case SUSPENDED = ;
            case UNVERIFIED = ;
            case DELETED = ;

            public function color(): string
            {
                return match ($this) self::ACTIVE     => ,
                    self::SUSPENDED  => ,
                    self::UNVERIFIED => ,
                    self::DELETED    => ,
                };
            }

            // label() ve description() aynı match şekli takip eder
        }
        

Sonuç olarak, görünüm durum üzerinde dallanmaz. Enum’dan sorar:


            {{ $user->status()->label() }}
        
        

Gelecek bir BANNED durumu eklemek istediğinizde, yalnızca bir dosyayı – enum’u – düzenlersiniz; her Blade şablonunu güncellemeye gerek kalmaz. Sunum, tanımladığı verilerle birlikte yaşar, ki bu da enum’a yöntemler vererek match bloklarını UI etrafında yaymanın asıl amacı olacaktır.



Durumu türetmek, bunu zorlamak değildir

Hesaplanan bir status() bir etiket gibidir. Bu askıya alınmış bir kullanıcının mevcut oturumunu kullanmasını engellemez – askıya alındıklarında, oturumda zaten oturum açmışlardı ve çerez bu enum’dan etkilenmez. Uygulama, middleware aracılığı ile ayrı ve kasten zorlanan bir sınırdır.

class EnsureUserIsNotSuspended
        {
            public function handle(Request $request, Closure $next): Response
            {
                $user = $request->user();

                if ($user && $user->isSuspended()) {
                    Auth::guard()->logout();

                    $request->session()->invalidate();
                    $request->session()->regenerateToken();

                    return redirect()
                        ->route()
                        ->with(, ());
                }

                return $next($request);
            }
        }
        

Not edin, yalnızca yönlendirme yapmaz – aynı zamanda logout(), oturumu geçersiz kılma ve CSRF tokenini yeniden oluşturma işlemlerini gerçekleştirir. Askıya almak, sürgün etmeli, basit bir rahatsızlık oluşturmak yerine. Yalnızca bir yönlendirme, çerezlerde geçerli bir oturum bırakabilir.



Pest: önceliği ve çıkışı belirleme

Kapalı tutmayı gerektiren iki şey vardır – bu match önceliğinin geçerli kalması ve middleware’in gerçekten askıya alınmış bir oturumu dışarı atması.

it(, function () {
            $user = User::factory()->create([=> now()]);

            expect($user->status())->toBe(UserStatus::ACTIVE);

            $user->suspend();
            expect($user->fresh()->status())->toBe(UserStatus::SUSPENDED);

            $user->delete(); expect($user->fresh()->status())->toBe(UserStatus::DELETED);
        });

        it(, function () {
            $user = User::factory()->create([=> now()]);
            $user->suspend();

            $this->actingAs($user)
                ->get()
                ->assertRedirect(route());

            expect(auth()->check())->toBeFalse();
        });
        

İlk test, zamanla değer kazanır: öncelik sırasını dondurur, böylece gelecekteki bir yeniden yapılandırma, SUSPENDED durumunu DELETED‘den öncelikli hale getiremez.



Çıkarım

Saklamanız gereken bir şeyi türetmeyin. Bir status sütunu uygun görünür, fakat dört sütuna dönüşür ve bunlar birbirleriyle çelişir. Diğerlerini email_verified_at ve deleted_at üzerinden alan yalnızca suspended_at için bir nullable timestamp saklayın ve status()‘u öncelik sırası ile sonuçlanacak match (true) ile hesaplayarak ve tek bir gerçeklik kaynağı olmasını sağlayın.

Sonunda atlanması kolay olan kısmı hatırlayın: bir durumu türetmek ve zorlamak iki ayrı işdir. Enum, hesabı etiketler; middleware ise gerçekten askıya alınmış bir kullanıcıyı dışarı atan yapıdır.

Kaynak: Orijinal Makale

Contents
  • Kısır döngü: bir status sütunu
  • Ne saklarız: bir nullable timestamp
  • Durum türetilmiştir, asla saklanmaz
  • Enum kendi sunumunu taşır
  • Durumu türetmek, bunu zorlamak değildir
  • Pest: önceliği ve çıkışı belirleme
  • Çıkarım
Laravel 11’de defer() Kullanarak API Cevaplarımızı Tek Bir Kuyruğa Dokunmadan 3 Kat Daha Hızlı Hale Getirme
Laravel için Nihai Yapay Zeka Ajanı (2026)
3 Saniyelik Tuzağı: HTML’den Laravel Blade’e Dönüşümlerin Neden Bu Kadar Yavaş Yükleniyor
Obsidian Admin Tanıtımı: Vue 3 + Laravel Yönetim Çerçevesi
Laravel Kısa Kodları Paketi – DEV Community
Bu Makaleyi Paylaş
Facebook Bağlantıyı Kopyala Yazdır
Paylaş
Önceki Makale Ooni Pizza Fırını Neden Bu Kadar Değerli?
Sonraki Makale AMD Grafik Kartları: Steam Donanım Araştırmasında Şaşırtan Sonuçlar

Sanal Medya

FacebookBeğen
452Takip Et
PinterestSabitle
237Takip Et

Son Eklenenler

Titanfall Tutkunları için Yenilikçi Empulse Deneyimi
Oyun
Zengin Adamlar İçin 25 Bin Dolara Trad Eşler Arayan Evlilik Danışmanları
Genel
Radeon RX 9070 XT Steam Donanım Anketinde RTX 5080’in Ardında
Donanım
PUBG Extraction Shooter Black Budget İçin İkinci Test Tarihi Açıklandı
Oyun
Govee’nin Şarjlı Akıllı Masa Lambası 60 Dolar Oldu
Liste
Kritik Uyarılar: Karanlık Web’de Tedarik Zinciri Saldırıları Belirtisi
Siber Güvenlik
//

Siber güvenlik, yapay zeka ve savunma sanayiinden; finans ve sinema dünyasına uzanan geniş bir yelpaze. Teknomers; teknoloji, strateji ve yazılım dünyasını sade bir dille sizlerle buluşturuyor.

Kurumsal

  • Hakkımızda
  • Gizlilik politikası
  • Tanıtım Yazısı ve Backlink Hizmeti

Kategoriler

  • Teknoloji
  • Oyun
  • Sinema
  • Siber Güvenlik
  • Bilim
  • Finans
  • Dünyadan Güncel Haberler

Populer

  • TV'de Ücretsiz İzlenebilen Şifresiz Erotik Kanallar (2025 Güncel Frekans Listesi)

  • The Last of Us PC Kontrolleri: Hızlı Silah Değiştirme ve Tüm Tuşlar (2025)

  • Hogwarts Legacy'de Odaklanma İksiri Nasıl Yapılır?

Teknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor Haberleri
Bizi Takip Et
© 2026 Teknomers. All Rights Reserved.
Welcome Back!

Sign in to your account

Kullanıcı Adı veya E-posta Adresi
Şifre

Şifrenizi mi unuttunuz?