Laravel fabrikaları, test yazmayı kolaylaştırır, özellikle birbiriyle bağlantılı modellere sahipseniz. Ancak bazen, ilk bakışta belli olmayan yollarla kafa karıştırıcı hale gelebilir. Bu konuda harika bir video izledim ve kendi görüşlerimi paylaşmak istiyorum.
Problem
Problem
Bir Client modeli düşünün ve aynı User modeline iki ilişkisinin olduğunu varsayın.
final class Client extends Model
{
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function distributor(): BelongsTo
{
return $this->belongsTo(User::class);
}
}
Bir test yazıyorsunuz:
$owner = UserFactory::new()->create(['name' => 'Owner']);
$distributor = UserFactory::new()->create(['name' => 'Distributor']);
$client = ClientFactory::new()
->for($owner)
->for($distributor)
->create();
Ne oluyor? Laravel, user_id değerini distribütörün ID’sine atıyor, sahibin ID’sine değil. distributor_id ise null kalıyor. Bu, istenilen durum değil.
Neden Bu Oluyor?
Neden Bu Oluyor?
Laravel bozuk değil, sadece kurallarına sadık kalıyor.
for($model) çağrıldığında, Laravel model tipine bakıyor, değişken adınıza değil. Hem $owner hem de $distributor User modeli. Laravel sizin düşüncenizi okuyamaz, bu yüzden bulduğu ilk ilişkiyi, yani user’ı alıyor. Değişken adları önemli değil.
Çözüm
Çözüm
Açık olmalısınız, Laravel’e hangi ilişkiyi kullanacağını belirtmelisiniz:
$client = ClientFactory::new()
->for($owner, 'user')
->for($distributor, 'distributor')
->create();
Artık her şey mükemmel çalışıyor. İkinci argüman, sadece ilişki adıdır.
Alternatif: for’ü atla
Alternatif: for’ü atla
Bazen doğrudan olmak daha nettir:
$client = ClientFactory::new()->create([
'user_id' => $owner->id,
'distributor_id' => $distributor->id,
]);
Burada yanlış bir şey yok. Açıkçası, bir dizi for() çağrısı yapmaktan daha net bir yöntemdir.
Konvansiyonlar Ne Zaman Çöker?
Konvansiyonlar Ne Zaman Çöker?
Laravel, konvansiyonlara uymadığınızda en iyi şekilde çalışır. Client modeli bir user ilişkisine sahipse, bu mükemmeldir. Ama bir modele ikinci bir ilişki eklerken, açık bir anlamsal fark yoksa kuralları biraz esnetiyorsunuz. Kendiliğinden Laravel gözünden bakıldığında, bu bir Distributor modeli eklemenizi bile önerebilir. Bu yanlış olduğu anlamına gelmez, bazen gerçekten aynı modelde birden fazla ilişkiye ihtiyacınız olur.
Bu nedenle ilişki adlarını açıkça belirtmek, her şeyi net tutar.
Mevcut projeme baktım ve for() ile açık ilişki adı kullanan pek fazla durum bulamadım.
Sadece bir tane buldum:
$address = AddressFactory::new()
->for($user)
->has(DirectionFactory::new()
->has(DirectionScheduleFactory::new()->count(10), 'schedules'))
->create();
İsimlendirme Önemlidir
İsimlendirme Önemlidir
Bazı isimlendirme iyileştirmeleri karışıklığı azaltabilir:
-
Client→Customer -
user→owner
İlişkiniz user olarak adlandırıldığında, ama alanınız “sahipler” diyorsa, gereksiz bir mental yük oluşturuyorsunuz. Açık isimler = daha az sürpriz.
Sonuç
Sonuç
Fabrikalar çok güçlüdür, ancak konvansiyonlara dayanır. Model tasarımınız bu konvansiyonlardan uzaklaştığında, açıklık sihirden daha iyidir:
- İlişki adını
for()metoduna geçirin veya - Yabancı anahtarları kendiniz ayarlayın.
Laravel tam olarak olması gerektiği gibi çalışıyor. Bizim görevimiz, niyetimizi net şekilde belirtmektir.
Yazar Notu
Yazar Notu
Okuduğunuz için teşekkürler!
Beni dev.to, LinkedIn üzerinden bulabilirsiniz veya GitHub üzerindeki çalışmalarımı kontrol edebilirsiniz.
Gerçek dünya Laravel notları.
Bu yazının ilhamını aldığım video için Joel Clermont’a teşekkürler. Onun Laravel ipuçları her zaman değerlidir.
Kaynak: Orijinal Makale


