TL;DR
- Bir e-posta yayın modülü yayınlandı: hedef kitle filtreleme, bastırma, alıcı başına kuyruklu gönderimler, teslimat takibi.
- Sessiz bir implicit-route-binding hatası düzeltildi — rota parametre adı, metot parametresiyle eşleşmediği için Laravel boş bir model enjekte etti.
- Günün dersi: Laravel’in implicit binding’i sessizce başarısız olur, gürültülü değil.
E-posta Yayınları
Bugünün ana konusu. Bir kampanya, bir hedef kitle filtresini bir iletişim sorgusuna çözümler, bunu bir bastırma kapısından geçirir (abone olmamış, iletişim kurulmaması gereken, e-posta yok), her iletişim için bir alıcı satırı oluşturur ve ardından her satır için bir kuyruklu iş gönderir.
Tasarım ilkesi: alıcı satırı gerçeklik kaynağıdır. Her iş, göndermeden önce satırın durumunu yeniden kontrol eder, bu nedenle bir tekrar veya çifte gönderim etkisizdir. Kilit yok, tekrar etme tablosu yok.
Teslimat web kancaları aynı satırlara geri senkronize edilir ve bir sıralama koruyucusu ile birlikte çalışır (sent < delivered < opened < clicked), böylece bir sıradışı olay asla durumu geriye almamalıdır. Terminal durumlar — geri gönderildi, abonelikten çıkıldı, başarısız — ayrı şekilde ele alınır.
Ayrıntılı yazım odaklı yazıda mevcut.
Hiçbir şey söylemeyen rota binding hatası
Bir gösterim sayfası Call to a member function label() on null hatası ile çöktü. Sebebi, iki isim arasında bir sürüklenme olmuş:
| Önce | Sonra | |
|---|---|---|
| Rota parametresi | {infraProvider} | {provider} |
| Mount imzası | mount(InfraProvider $provider) | mount(InfraProvider $provider) |
| Sonuç | boş model enjekte edildi | doğru model |
// rota
Route::get('/{provider}', ProviderShow::class)->name('show');
// bileşen
public function mount(InfraProvider $provider): void { / ... / }
Hatırlanması gereken kısım: Laravel, implicit route-model bağlamalarını isimle eşleştirir. URI segmenti {infraProvider}, $provider değişkeni ile eşleşmelidir. Eşleşmediğinde, bir istisna almazsınız — yeni bir, boş model alırsınız. id 0’dır, her özellik boş ve başarısızlık, üç katman sonra bir null enum üzerine bir metot çağrıldığında ortaya çıkar.
Bu, gizli bir hata. Sayfa, daha önce gerçek verilerle açılmamıştı, bu yüzden hiç kimse fark etmedi. İlk kaydı oluşturmak sorunu hemen ortaya çıkardı.
Düzeltme, parametreyi kardeş kaynak rotalarına eşleşecek şekilde yeniden adlandırmaktı ({project}, {team}). Bir rota dosyası genelinde tutarlılık burada düşük maliyetli bir savunmadır — her rota tekil model adını kullanıyorsa, uyumsuzluk asla gerçekleşmez.
it('gösterim rotasında sağlayıcı çözümlemesi', function () {
$provider = InfraProvider::factory()->create();
<span class="nf">get</span><span class="p">(</span><span class="nf">route</span><span class="p">(</span><span class="s1">'providers.show'</span><span class="p">,</span> <span class="nv">$provider</span><span class="p">))</span>
<span class="o">-></span><span class="nf">assertOk</span><span class="p">()</span>
<span class="o">-></span><span class="nf">assertSee</span><span class="p">(</span><span class="nv">$provider</span><span class="o">-></span><span class="n">name</span><span class="p">);</span>
});
Gerçek rotaya giden bir test bunu yakalayabilirdi. Bileşeni ayrı ayrı test etmek yeterli olmadı — bağlama, yönlendirici sınavları yaparken gerçekleşir.
Veri Tohumu Olarak Buhar Testi
Diğer commit, gerçekçi bir başlangıç ortamı sağlamak için idempotent, yapılandırma bazlı bir seeder oldu, bu da sahte satırlardan daha güvenilir. Aynı gün içinde faydasını gördü — hiç kullanılmamış bir sayfada ilk gerçek kaydı üretti ve bu, bağlama hatasının yüzeye çıkmasına neden oldu. İyi bir seeder, geride faydalı veriler bırakan bir buhar testidir.
Sonuç
Geçerli görünen boş bir nesne döndüren hatalar, istisnalardan daha kötüdür. Konvansiyon — isimlerin eşleşmesi, tutarlı rota parametreleri — bu hataları oluşmadan önce engeller.
Kaynak: Orijinal Makale


