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.
