Laravel İle İlişkisel Veritabanı Eloquent İlişki Kurma Nasıl Yapılır?

Laravel İle İlişkisel Veritabanı Eloquent İlişki Kurma Nasıl Yapılır?
Laravel İle İlişkisel Veritabanı Eloquent İlişki Kurma Nasıl Yapılır?

Ön Hazırlık ve Gereksinimler

Eloquent ilişkilerini uygulamaya başlamadan önce sisteminizde Laravel 11 veya üzeri bir sürümün kurulu olması önerilir. Veritabanı işlemlerini yönetmek için MySQL, PostgreSQL veya SQLite gibi bir veritabanı sürücüsünün yapılandırılmış olması gerekir.

  • PHP 8.2+ sürümü yüklü olmalıdır.
  • Composer paket yöneticisi ile Laravel projenizi oluşturmuş olmalısınız.
  • .env dosyanızda veritabanı bağlantı bilgilerinizin doğru tanımlandığından emin olun.

Projenin kök dizininde terminalinizi açarak php artisan --version komutu ile güncel sürümünüzü kontrol edebilirsiniz.

One-to-One (Bire-Bir) İlişki Kurma

Bire-bir ilişki, bir kaydın başka bir tabloda sadece bir karşılığı olduğu durumlarda kullanılır. Örneğin, bir "User" (Kullanıcı) modelinin sadece bir "Profile" (Profil) kaydı olabilir.

Öncelikle User modelinizde ilgili ilişki metodunu tanımlamalısınız. Aşağıdaki kod örneği, bir kullanıcının profile sahip olduğunu belirtir:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;

class User extends Model
{
    public function profile(): HasOne
    {
        return $this->hasOne(Profile::class);
    }
}

Bu metod, Eloquent'in profiles tablosunda user_id sütununu otomatik olarak aramasını sağlar. İlişkiyi test etmek için $user->profile şeklinde veriye erişebilirsiniz.

Many-to-Many (Çok-Çok) İlişki Kurma

Çok-çok ilişkilerde, iki tablo arasında aracı bir tabloya (pivot table) ihtiyaç duyulur. Örneğin, "Post" ve "Tag" (Etiket) ilişkisi. Bir gönderinin birden fazla etiketi olabilir, bir etiket de birden fazla gönderide kullanılabilir.

Bu ilişkiyi kurmak için belongsToMany metodunu kullanırız. Aşağıdaki örnek, Post modelinde etiketleri nasıl tanımlayacağınızı gösterir:

public function tags()
{
    return $this->belongsToMany(Tag::class, 'post_tag', 'post_id', 'tag_id');
}

Burada post_tag aracı tablonun adıdır. Eğer Laravel isimlendirme standartlarına (alfabetik sıra) uyduysanız, sadece return $this->belongsToMany(Tag::class); yazmanız yeterlidir.

Eloquent İlişki Yöntemleri Karşılaştırma Tablosu

İlişki Türü Metod Kullanım Amacı
Bire-Bir hasOne / belongsTo Tekil eşleşmeler (Kullanıcı-Profil)
Bire-Çok hasMany / belongsTo Çoğul eşleşmeler (Kullanıcı-Gönderiler)
Çok-Çok belongsToMany Karmaşık ağlar (Gönderi-Etiketler)

Performans: Eager Loading (İstekli Yükleme)

Eloquent ilişkilerinde en sık yapılan hata "N+1" sorunudur. Eğer bir döngü içerisinde ilişkili verileri çekerseniz, her döngü için ayrı bir veritabanı sorgusu çalışır. Bunu engellemek için with() metodunu kullanmalısınız.

// Hatalı (N+1 sorunu yaratır)
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->comments->count();
}

// Doğru (Tek sorguda tüm ilişkili verileri çeker)
$posts = Post::with('comments')->get();
foreach ($posts as $post) {
    echo $post->comments->count();
}

Bu yöntem, uygulamanızın veritabanı yükünü ciddi oranda azaltır ve sayfa yüklenme hızını artırır.

Kritik Güvenlik Uyarısı: İlişkisel veritabanı işlemlerinde kullanıcıdan gelen verileri asla doğrudan sorguya dahil etmeyin. Laravel'in sunduğu "Query Builder" ve "Eloquent" metotları SQL Injection saldırılarına karşı koruma sağlar. Ancak, raw sorgular kullanmanız gerekiyorsa mutlaka DB::raw() veya parametre bağlama (binding) yöntemlerini tercih edin.

Sıkça Sorulan Sorular

Eloquent ilişkilerinde aracı tabloyu nasıl özelleştiririm?

belongsToMany metodunun ikinci parametresine tablonun adını, üçüncü ve dördüncü parametrelerine ise ilgili yabancı anahtar (foreign key) isimlerini vererek özelleştirebilirsiniz.

İlişkili verileri nasıl silerim?

İlişkili kayıtları silmek için delete() metodunu kullanabilirsiniz. Ancak veritabanı seviyesinde "Cascade Delete" (zincirleme silme) kullanmak, verilerin tutarlılığı açısından daha güvenlidir.

Bir modelin ilişkisi olup olmadığını nasıl kontrol ederim?

has() veya whereHas() metotlarını kullanarak, belirli bir ilişkiye sahip olan modelleri kolayca filtreleyebilirsiniz.

Pivot tablodaki verilere nasıl erişirim?

$post->tags()->withPivot('created_at')->get() şeklinde pivot tablodaki ek sütunlara erişim sağlayabilirsiniz.

Neden `belongsTo` yerine `hasOne` kullanmalıyım?

`belongsTo` yabancı anahtarın (foreign key) bulunduğu modelde kullanılır. `hasOne` ise karşı taraftaki modelde kullanılır. İlişkiyi kurarken anahtarın hangi tabloda olduğuna dikkat etmelisiniz.

Polimorfik İlişkiler ile Esnek Veri Modelleri

Standart ilişkilerin ötesine geçmek istediğinizde, Laravel'in sunduğu Polimorfik İlişkiler devreye girer. Bu yapı, bir modelin birden fazla farklı modelle tek bir ilişki üzerinden bağlanmasını sağlar. Örneğin, bir Comment (Yorum) modeliniz olduğunu ve bu yorumların hem Post (Gönderi) hem de Video modellerine ait olabileceğini düşünün.

Polimorfik İlişki Kurulumu

Bu yapıyı kurmak için veritabanınızda iki özel sütuna ihtiyacınız vardır: commentable_id (ilgili modelin ID'si) ve commentable_type (ilgili modelin sınıf ismi). Migration dosyanızda şu yapıyı kullanmalısınız:

Schema::create('comments', function (Blueprint $table) {
    $table->id();
    $table->text('body');
    $table->morphs('commentable'); // commentable_id ve commentable_type oluşturur
    $table->timestamps();
});

Ardından model tarafında ilişkiyi şu şekilde tanımlarsınız:

// Comment.php
public function commentable()
{
    return $this->morphTo();
}

// Post.php
public function comments()
{
    return $this->morphMany(Comment::class, 'commentable');
}

Eloquent İlişkilerinde Hata Ayıklama ve Sorgu İzleme

İlişkiler karmaşıklaştıkça, Eloquent'in arka planda hangi SQL sorgularını çalıştırdığını görmek hata ayıklama sürecini hızlandırır. Laravel'in DB::enableQueryLog() özelliğini kullanarak ilişkilerinizin veritabanını nasıl yorduğunu analiz edebilirsiniz.

Sorgu Günlüğünü Kullanma

Geliştirme aşamasında bir rotada veya test sınıfında şu yöntemi kullanarak ilişkilerinizin performansını ölçebilirsiniz:

\DB::enableQueryLog();

$posts = Post::with('comments')->get();

dd(\DB::getQueryLog());

Bu çıktı size kaç adet sorgu çalıştığını ve bu sorguların ne kadar sürdüğünü gösterir. Eğer N+1 problemi yaşıyorsanız, with() metodunun doğru çalışıp çalışmadığını bu günlükler üzerinden kolayca tespit edebilirsiniz. Unutmayın, ilişkilerinizde lazy loading (tembel yükleme) yerine eager loading (istekli yükleme) kullanmak, veritabanı yükünüzü %80'e varan oranlarda azaltabilir.

İleri İpucu: İlişki Sorgularını Filtreleme

Bazen sadece belirli koşulları sağlayan ilişkili verileri çekmek istersiniz. Örneğin, sadece onaylanmış yorumları getirmek için ilişki tanımlamanızda şu filtrelemeyi kullanabilirsiniz:

public function approvedComments()
{
    return $this->hasMany(Comment::class)->where('is_approved', true);
}

Bu yöntem, ilişkili verileri ana model üzerinden çekerken ekstra bir where sorgusu yazmanıza gerek kalmadan, doğrudan $post->approvedComments şeklinde temiz bir kullanım sağlar.

Sonuç

Laravel ile ilişkisel veritabanı Eloquent ilişki kurma işlemleri, uygulama mimarinizi temiz ve sürdürülebilir kılmak için temel bir beceridir. Bu rehberde öğrendiğiniz hasOne, hasMany ve belongsToMany metotları, çoğu projenin omurgasını oluşturur. Bir sonraki adım olarak, "Polymorphic Relationships" (Polimorfik İlişkiler) konusunu inceleyerek, tek bir modelin birden fazla farklı modelle nasıl ilişki kurabileceğini öğrenebilirsiniz.

Kod güvenliğiniz için her zaman güncel Laravel dokümantasyonunu takip edin ve uygulamalarınızı üretim (production) ortamına almadan önce tüm ilişkilerinizi birim testleri (unit tests) ile doğrulayın.

Bu yazıya tepkinizi paylaşın:
Mert Demir

Teknik beceriler ve bakım onarım rehberleri konusunda deneyimli bir editörüm. Okuyucularıma günlük hayatta tasarruf sağlayacak ipuçları sunuyorum.

Yorumlar (18)

18
okuyucu bu yazı hakkında yorum yaptı. Siz de deneyiminizi paylaşarak diğer okuyuculara yardımcı olabilirsiniz.
Mehmet Ali
Mehmet Ali 12 Temmuz 2026

Kod bloklarını daha belirgin yapsan çok daha iyi olurdu sanki, biraz iç içe geçmiş gibi duruyor.

Ahmet Y.
Ahmet Y. 14 Temmuz 2026

Bence gayet okunabilir duruyor ya, sorun yok bence.

Gözde M.
Gözde M. 16 Temmuz 2026

Arkadaşın dediği gibi morp ilişkileride anlatırsan tam olur aslında, bekliyoruz.

Mert Demir
Mert Demir 17 Temmuz 2026

Notumu aldım Gözde, bir sonraki içerik planına ekliyorum.

Kaan Çelik
Kaan Çelik 18 Temmuz 2026

ManyToMany ilişkilerde pivot tablosuna ekstra sütun eklerken hata yapıyordum, sayende çözdüm. Eyvallah.

Mustafa B.
Mustafa B. 22 Temmuz 2026

hocam ellerine saglık cok guzel olmus gercekten uzun zamandır boyle net anlatan gormedım

Ece Nur
Ece Nur 24 Temmuz 2026

Katılıyorum, gerçekten çok açıklayıcı olmuş.

Deniz Yıldız
Deniz Yıldız 25 Temmuz 2026

Yazı için teşekkürler, gayet sade ve anlaşılır olmuş. Başarılar.

Hakan K.
Hakan K. 28 Temmuz 2026

Laravel 11 ile gelen değişikliklerden sonra bu yöntemler hala geçerli mi?

Mert Demir
Mert Demir 29 Temmuz 2026

Evet Hakan, Eloquent çekirdeği aynı olduğu için bu yöntemler Laravel 11'de de sorunsuz çalışıyor.

Zeynep S.
Zeynep S. 30 Temmuz 2026

Ya ben kodları kopyalayıp yapıstırdım ama hata alıyom, anlamadım gitti neden böyle oluyo ki?

Mert Demir
Mert Demir 31 Temmuz 2026

Zeynep, aldığın hata kodunu paylaşırsan yardımcı olabilirim. Muhtemelen namespace veya model isimlendirmesinde bir gözden kaçan detay vardır.

Burak Özdemir
Burak Özdemir 01 Ağustos 2026

Abi çok güzel anlatmışsın da, 'morphTo' ilişkisi biraz havada kalmış sanki. Onunla ilgili de bi kısım olsa efsane olurdu.

Fatih Terimci
Fatih Terimci 02 Ağustos 2026

Aynen katılıyorum, polymorphic ilişkiler biraz karmaşık gerçekten.

Selin A.
Selin A. 03 Ağustos 2026

Ya bu eager loading mevzusunu hala tam kavrayamadım, n+1 sorunu için bi örnek daha ekleyebilir misin?

Mert Demir
Mert Demir 04 Ağustos 2026

Selin, n+1 konusu çok kritik. En kısa sürede sadece ona özel bir rehber hazırlayıp detaylıca örneklendireceğim, takipte kal.

Caner Yılmaz
Caner Yılmaz 05 Ağustos 2026

Eline sağlık Mert hocam, tam da projede hasMany kullanırken kafam karışmıştı, ilaç gibi geldi yazı.

Mert Demir
Mert Demir 06 Ağustos 2026

Rica ederim Caner, yardımcı olabildiysem ne mutlu bana. Kolay gelsin!

Yorum Yaz