Laravel'de Polymorphic Many-to-Many İlişkisi

L

Laravel, veritabanı ilişkilerini kolayca yönetebilmenizi sağlayan güçlü bir ORM olan Eloquent sunar. Polymorphic ilişkiler, farklı türdeki modellerin aynı ilişkiyi paylaşmasına olanak tanır. Özellikle Polymorphic Many-to-Many ilişkisi, farklı türlerdeki modellere ait verilerin dinamik bir şekilde birbirine bağlanmasını sağlar.

Bu yazıda, Polymorphic Many-to-Many ilişkisini kurmanın yanı sıra, ilişkili modelleri eklemek (attach) ve kaldırmak (detach) işlemlerini de nasıl yapacağınızı anlatacağım. Kod örnekleriyle, Tag, Post ve Video modelleri üzerinden tam bir örnek üzerinden anlatım yapacağım. Ayrıca, Pivot modeli ve enforceMorphMap özelliğini de ele alacağız.

Polymorphic Many-to-Many İlişkisi Nedir?

Polymorphic Many-to-Many ilişkisi, bir modelin birden fazla modele ait olabilmesini ve bu ilişkilerin birbirine bağlı olmasını sağlar. Laravel, polymorphic ilişkileri kolayca yönetebilmenize olanak tanır.

Örneğin, bir Tag modeli hem Post hem de Video modellerine ait olabilir. Bu durumda, aynı Tag birden fazla model ile ilişkilendirilebilir.

Veritabanı Yapısı

Öncelikle, polymorphic ilişkileri oluşturacağımız veritabanı yapısını kurmalıyız. Bu yapıda, tags, posts, videos ve taggables tablosu olacak.

1. Migration Dosyaları

Tags Tablosu:

Schema::create('tags', function (Blueprint $table) {
    $table->id();
    $table->string('name'); // Etiket ismi
    $table->timestamps();
});

Posts Tablosu:

Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title'); // Yazı başlığı
    $table->text('content'); // Yazı içeriği
    $table->timestamps();
});

Videos Tablosu:

Schema::create('videos', function (Blueprint $table) {
    $table->id();
    $table->string('title'); // Video başlığı
    $table->text('url'); // Video URL'si
    $table->timestamps();
});

Taggable Pivot Tablosu:

Schema::create('taggables', function (Blueprint $table) {
    $table->id();
    $table->foreignId('tag_id')->constrained(); // Etiket referansı
    $table->morphs('taggable'); // Polymorphic ilişkiler için taggable_id ve taggable_type sütunları
    $table->timestamps();
});

Bu migration dosyaları ile, polymorphic ilişkiler için gerekli yapıyı oluşturmuş olduk.

Modellerin Kurulumu

Şimdi, oluşturduğumuz modelleri kurarak ilişkileri tanımlayacağız.

2. Modellerin İlişkilerinin Tanımlanması

Tag Modeli:

Tag modelinde, hasMany ilişkisini Taggable pivot modeli üzerinden kuracağız.

class Tag extends Model
{
    // Tag'e ait ilişkileri tanımlar
    public function taggables()
    {
        return $this->hasMany(Taggable::class);
    }
}

Post Modeli:

Post modelinde, polymorphic many-to-many ilişkisini morphToMany ile tanımlıyoruz.

class Post extends Model
{
    // Post'un ilişkili olduğu Tag'leri alır
    public function tags()
    {
        return $this->morphToMany(Tag::class, 'taggable');
    }
}

Video Modeli:

Benzer şekilde, Video modeli de morphToMany kullanarak Tag ile ilişkilendirilir.

class Video extends Model
{
    // Video'nun ilişkili olduğu Tag'leri alır
    public function tags()
    {
        return $this->morphToMany(Tag::class, 'taggable');
    }
}

Taggable Pivot Modeli:

Pivot model, polymorphic ilişkiyi yönetir. Bu modelde morphTo() fonksiyonunu kullanarak, her ilişkili modelin türünü çözümleyeceğiz.

class Taggable extends Pivot
{
    // İlgili modeli çözümlemek için morphTo() kullanıyoruz
    public function taggable()
    {
        return $this->morphTo();
    }
}

3. Veriye Erişim

Veritabanındaki ilişkileri kurduktan sonra, ilişkilere kolayca erişebilirsiniz.

// Bir tag'in ilişkili olduğu tüm modelleri al
$tag = Tag::find(1); // ID'si 1 olan tag
$relatedModels = $tag->taggables->pluck('taggable');

// İlgili tüm modelleri görmek
foreach ($relatedModels as $model) {
    if ($model instanceof Post) {
        echo "Bu bir Post modelidir: " . $model->title;
    } elseif ($model instanceof Video) {
        echo "Bu bir Video modelidir: " . $model->title;
    }
}

Bu kod örneği, Tag modeline ait tüm ilişkili modelleri alır ve her birini türüne göre kontrol eder.

Attach ve Detach İşlemleri

Laravel, polymorphic ilişkilerle çalışırken attach ve detach gibi ilişkileri dinamik olarak eklemenize veya çıkartmanıza olanak tanır. İşte bu işlemlerin nasıl yapılacağını detaylı olarak inceleyelim.

4. Attach İşlemi

Bir Tag'i Post veya Video gibi modellerle ilişkilendirmek için attach yöntemini kullanabilirsiniz.

Post ile ilişki eklemek:

// Tag'i bir Post ile ilişkilendir
$post = Post::find(1);
$tag = Tag::find(1);

$post->tags()->attach($tag); // Bu tag'i bu post'a ekler

Video ile ilişki eklemek:

// Tag'i bir Video ile ilişkilendir
$video = Video::find(1);
$tag = Tag::find(1);

$video->tags()->attach($tag); // Bu tag'i bu video'ya ekler

5. Detach İşlemi

Bir ilişkiden bağlantıyı kaldırmak için detach yöntemini kullanabilirsiniz.

Post ile ilişkiden bağlantıyı kaldırmak:

// Tag'i bir Post ile ilişkiden çıkar
$post = Post::find(1);
$tag = Tag::find(1);

$post->tags()->detach($tag); // Bu tag'i bu post'tan çıkarır

Video ile ilişkiden bağlantıyı kaldırmak:

// Tag'i bir Video ile ilişkiden çıkar
$video = Video::find(1);
$tag = Tag::find(1);

$video->tags()->detach($tag); // Bu tag'i bu video'dan çıkarır

6. Sync İşlemi

Birden fazla etiketi aynı anda ilişkilendirmek veya kaldırmak için sync metodunu kullanabilirsiniz. Bu metod, sadece belirtilen ilişkileri korur ve diğerlerini siler.

// Birden fazla tag ekleyip, eski ilişkileri sil
$post = Post::find(1);
$post->tags()->sync([1, 2, 3]); // 1, 2, 3 ID'li tag'leri post ile ilişkilendir

Enforce Morph Map Kullanımı

Polymorphic ilişkilerde, model isimlerini kısaltmak ve daha güvenli hale getirmek için enforceMorphMap özelliğini kullanabiliriz. Bu özellik, polymorphic ilişkilerde kullanılan tür adlarını belirleyip bu adların hangi modellere karşılık geldiğini tanımlar.

1. Morph Map Nedir?

Morph map, polymorphic ilişkilerde belirli bir tür adı ile ilişkilendirilen modeli belirler. Örneğin, user türü ile User modelini ilişkilendirmek için morph map kullanabilirsiniz.

2. Enforce Morph Map Kullanımı

enforceMorphMap fonksiyonunu, AppServiceProvider veya uygulamanızın herhangi bir uygun yerinde tanımlayabilirsiniz.

use Illuminate\Database\Eloquent\Relations\Relation;

public function boot()
{
    Relation::enforceMorphMap([
        'user' => User::class, // user türünü User modeline eşle
        'post' => Post::class, // post türünü Post modeline eşle
    ]);
}

Bu, polymorphic ilişkilerdeki taggable_type alanındaki user veya post türlerinin sırasıyla User ve Post modellerine karşılık gelmesini sağlar.

3. Pivot Modelde Enforce Morph Map Kullanımı

class Taggable extends Pivot
{
    // İlgili modeli çözümlemek için morphTo() kullanıyoruz
    public function taggable()
    {
        return $this->morphTo();
    }
}

Veriye Erişim Örneği:

$tag = Tag::find(1);
$relatedModels = $tag->taggables->pluck('taggable');

// Her modelin türünü kontrol etme
foreach ($relatedModels as $model) {
    if ($model instanceof User) {
        echo "Bu bir User modelidir.";
    } elseif ($model instanceof Post) {
        echo "Bu bir Post modelidir.";
    }
}

Sonuç

Laravel'de Polymorphic Many-to-Many ilişkileri, modellerin birbirleriyle esnek ve dinamik bir şekilde ilişkilenmesini sağlar. Pivot modelleri ve morphTo() fonksiyonu, ilişkilerinizi daha etkili yönetmenize olanak tanır. Ayrıca, Relation::enforceMorphMap ile polymorphic ilişkilerdeki tür adlarını güvenli ve anlaşılır bir şekilde yönetebilirsiniz.

Bu yazıda, ilişkilerinizi nasıl kuracağınızdan, veriye nasıl erişebileceğinize ve enforceMorphMap ile tür güvenliğini nasıl artıracağınızdan bahsettik.

By Aydın Yağız

Aydın Yağız

Teknolojiye olan tutkumla inovasyonu destekler, kullanıcı deneyimini önceliklerim arasına alırım. Kendi yeteneklerimi ve bilgilerimi paylaşarak, daha geniş bir topluluğun faydalanmasını sağlarım. İş birliği içinde hareket ederek, geleceğin teknoloji dünyasına katkıda bulunmayı hedeflerim. Sizi de bu heyecan verici yolculuğa davet ediyor, fikirlerinizi paylaşmaya ve teknolojiye dair sınırları zorlamaya teşvik ediyorum. Birlikte büyüyelim ve yeni ufuklara açılalım!

İletişime Geçin

Kodlama dünyasına adım atın ve deneyimlerinizi paylaşın. Siz de bu aktif topluluğa katılarak yeni bağlantılar kurun, fikir alışverişinde bulunun ve bilgi birikiminizi artırın.

Özelleştir

Farklı yazı tipleri ve renk seçenekleriyle stilinizi kişiselleştirin. Aşağıdaki örneklerden birini deneyerek sizin için en uygun olanı seçin.

Yazı Tipi Örnekleri

Renk Örnekleri